¿Qué tipo de función puedo usar para saber cuántos elementos hay en una matriz char?
sizeof () da la cantidad de «espacios» disponibles, por lo que no me funciona.
Comentarios
Responder
Quieres strlen
.
char foo [100] = "bar"; Serial.println (strlen (foo)); // --> prints 3
Comentarios
- Si la respuesta le funcionó, haga clic en el botón " accept " (parece una marca de verificación). De esa manera, otras personas sabrán que el La solución funcionó.
- Tuve que esperar un par de minutos para hacerlo
- Tenga en cuenta que esto solo funcionará si los datos en su contiene una cadena ascii y tiene una terminación nula adecuada. Además, si tiene una cadena larga en
char[]
, y la sobrescribe con una cadena más corta sin agregar la terminación nula, obtendrá el tamaño de la cadena anterior. - Muy bien. Mi respuesta fue para la pregunta tal como se presentó. Las cosas que mencionas deben tenerse en cuenta para las cadenas C terminadas en nulo.
Responder
Te conozco tengo tu respuesta de @NickGammon, pero me gustaría agregar un poco más de información detallada sobre cómo funciona todo esto.
sizeof()
no es un función en el sentido normal de la palabra. Es un operador que le da el número de bytes de memoria asignados a lo que le pasa. Si le pasa una matriz, entonces devuelve el número de bytes que la matriz tiene disponible. Si le pasa un puntero a una matriz, devuelve el tamaño de ese puntero, no el tamaño de la matriz. Si le pasa una variable entera, devuelve el número de bytes utilizados por esa variable entera (2 en una variable de 8 bits sistema como AVR, 4 en un sistema de 32 bits como Due).
Así que algunos ejemplos:
char array[50] = "hello"; // sizeof(array) = 50. char *array_p = array; // sizeof(array_p) = 2 or 4 depending on architecture. char single = "a"; // sizeof(single) = 1. char string[] = "hello"; // sizeof(string) = 6 (5 letters plus \0) - it allocates the memory at compile time to fit the string
Ahora strlen()
. ¿En qué se diferencia exactamente de sizeof()
? En pocas palabras, cuenta el número de caracteres en una matriz de caracteres hasta que alcanza el carácter \0
que es el carácter final» NULL «de una cadena C. Tomemos los ejemplos anteriores, pero usemos strlen en su lugar:
char array[50] = "hello"; // strlen(array) = 5. char *array_p = array; // strlen(array_p) = 5. char single = "a"; // strlen(single) = ERROR! strlen() doesn"t operate on single characters. char string[] = "hello"; // strlen(string) = 5.
Observa que siempre devuelve el número de caracteres en la cadena hasta, pero sin incluir, el carácter \0
final.
En su forma más simple, la función strlen()
podría verse así:
int strlen(const char *data) { int c = 0; const char *p = data; while (*p) { c++; p++; } return c; }
Básicamente, comienza en el primer carácter de la cadena (*p = data
), examina si es «sa \0
o no (while (*p)
), incrementa el recuento de caracteres (c++
) y pasa al siguiente carácter en la cadena (p++
).
Si desea iterar a través de su cadena en su programa, puede llamar a strlen()
primero para obtener el número de caracteres en la cadena, luego use ese valor en un bucle. Eso es un poco desperdicio, ya que strlen()
primero itera a través de la cadena, por lo que terminas iterando dos veces. Es mucho más eficiente aprender la mejor manera de recorrer cada carácter de la cadena hasta encontrar el carácter final, por ejemplo, cómo la función strlen()
usa el puntero moverse por la memoria. También puede ver lo importante que es asegurarse de que el carácter \0
exista al final de la cadena; de lo contrario, ¿cómo funcionará como strlen()
¿Sabes cuándo parar? No pueden saber cuánto mide la cadena (sizeof()
devolverá el tamaño del puntero que se pasa, no el tamaño de la matriz), por lo que deben tener algún tipo de marcador manual, y la convención en C es usar \0
.
Tenga en cuenta que las funciones print()
de Arduino en realidad hazlo de manera muy ineficiente. Si hace algo como:
char message[] = "Hello"; Serial.println(message);
Realmente hará bastante trabajo que no «t realmente necesita. Tomado paso a paso:
- llama a println (mensaje)
- que llama a escribir (mensaje)
- que obtiene la longitud de la cadena con strlen (mensaje)
- y llama a escribir (mensaje, longitud)
- que luego recorre de 0 a longitud-1 enviando cada carácter del mensaje a escribir () a su vez.
- finalmente imprime el
\r\n
para la nueva línea.
Así que en realidad termina anidado alrededor de 4 funciones de profundidad e itera la cadena completa dos veces. ejemplo clásico de cómo perder el tiempo de procesamiento.Al iterar a través de la cadena una vez buscando el carácter \0
en la función write(message)
(paso 2), funcionaría al menos dos veces más rápido. Buen viejo Arduino …
Comentarios
- Re «En su forma más simple, la función strlen () podría verse así», en una ( ¿quizás más simple?) forma podría verse así:
int strlen(const char *data) { const char *p = data; while (*p++); return p-data-1; }
- @ jwpat7 Dije " más simple ", no " más corto y compacto ". Esa forma, aunque más pequeña y eficiente, es mucho más difícil de entender para el OP (que obviamente no es un programador).
- De acuerdo 🙂 También es más fácil cometer errores en Y si
\0
es el último byte accesible en un segmento, el*p++
fallará. Peroint strlen(const char *data) { const char *p = data; while (*p) ++p; return p-data; }
evita ese problema. - En realidad,
*p++
ganó ' t falla incluso si\0
es el último byte accesible en un segmento; la parte*p
accederá al último byte; la parte ++ estableceráp
en una dirección no válida; pero como esa dirección inválida no ' no se hace referencia, en una máquina típica no ocurre ninguna falla. - Es una macro en tiempo de compilación … Es ' no es una macro , es ' un operador (como " + " y " – " son operadores). Son de un nivel más bajo que las macros, que son cosas que se hacen en el momento del preprocesador. Consulte tamaño del operador . También Operadores en C ++
Responder
use sizeof char nnn[10]; for(int i=0; i< sizeof(nnn)/sizeof(char); i++){ }
Comentarios
- ¿Leíste correctamente la pregunta?
- El OP dijo
sizeof
" no ' me funciona " y entonces sugieres usar sizeof. - No puedo responder la pregunta cuando usas el mismo desconocido
char foo [100] = "bar";
– ¿es eso lo que quieres decir? ¿Quieres la respuesta: 3?