Que tipo de função posso usar para saber quantos elementos estão em uma matriz char?
sizeof () fornece o número de “espaços” disponíveis, então não funciona para mim.
Comentários
Resposta
Você deseja strlen
.
char foo [100] = "bar"; Serial.println (strlen (foo)); // --> prints 3
Comentários
- Se a resposta funcionou para você, clique no botão " aceitar " (parece um tique). Dessa forma, outras pessoas saberão que o solução funcionou.
- Tive de esperar alguns minutos para fazer isso
- Observe que isso apenas funcionará se os dados em seu contém uma string ascii e é devidamente terminado em nulo. Além disso, se você tiver uma string longa em
char[]
e substituí-la por uma string mais curta sem adicionar a terminação nula, obterá o tamanho da string mais antiga. - Exatamente. Minha resposta foi para a pergunta apresentada. As coisas que você mencionou devem ser levadas em consideração para strings C terminadas em nulo.
Resposta
Eu conheço você tem sua resposta de @NickGammon, mas gostaria apenas de adicionar informações mais detalhadas sobre como tudo isso funciona.
sizeof()
não é um função no sentido normal da palavra. É um operador que lhe dá o número de bytes de memória alocados para tudo o que você passa para ele. Se você passar um array, ele retorna o número de bytes que o array tem disponível. Se você passar um ponteiro para um array, ele retornará o tamanho desse ponteiro, não o tamanho do array. Se você passar uma variável inteira, ele retornará o número de bytes usados por essa variável inteira (2 em um 8 bits sistema como AVR, 4 em um sistema de 32 bits como o Due).
Então, alguns exemplos:
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
Agora strlen()
. Exatamente como isso difere de sizeof()
? Simplificando, conta o número de caracteres em uma matriz de caracteres até atingir o caractere \0
, que é o caractere de terminação” NULL “de uma string C. Vamos pegar os exemplos anteriores, mas usar strlen em vez disso:
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.
Você notou que sempre retorna o número de caracteres na string até, mas não incluindo, o caractere \0
final.
Em sua forma mais simples, a função strlen()
pode ter a seguinte aparência:
int strlen(const char *data) { int c = 0; const char *p = data; while (*p) { c++; p++; } return c; }
Basicamente, ele começa no primeiro caractere da string (*p = data
) e examina se “sa \0
ou não (while (*p)
), incrementa a contagem de caracteres (c++
) e passa para o próximo caractere na string (p++
).
Se quiser iterar por meio da string no programa, você pode chamar strlen()
primeiro para obter o número de caracteres na string, em seguida, use esse valor em um loop. Isso é um desperdício, já que strlen()
itera primeiro pela string, então você acaba iterando duas vezes. É muito mais eficiente aprender a melhor forma de percorrer cada caractere na string até encontrar o caractere final, por exemplo, como a função strlen()
usa o ponteiro para se mover pela memória. Você também pode ver o quão importante é garantir que o \0
caractere exista no final da string, caso contrário, como funcionará como strlen()
sabe quando parar? Eles não podem “saber o tamanho da string (sizeof()
retornará o tamanho do ponteiro que é passado, não o tamanho do array), então eles precisam ter algum tipo de marcador manual, e a convenção em C é usar \0
.
Observe que as funções do Arduino “s print()
na verdade faça isso de forma muito ineficiente. Se você fizer algo como:
char message[] = "Hello"; Serial.println(message);
Na verdade, fará um bocado de trabalho que não realmente precisa. passo a passo:
- chama println (mensagem)
- que chama write (mensagem)
- que obtém o comprimento da string com strlen (mensagem)
- e chama write (message, length)
- que então faz um loop de 0 a length-1 enviando cada caractere da mensagem para write () por vez.
- finalmente imprime o
\r\n
para a nova linha.
Portanto, na verdade, termina aninhado em torno de 4 funções profundas e itera a string inteira duas vezes. exemplo clássico de como desperdiçar tempo de processamento.Ao iterar pela string uma vez à procura do \0
caractere na função write(message)
(etapa 2), ele operaria pelo menos duas vezes mais rápido. O bom e velho Arduino …
Comentários
- Re “Em sua forma mais simples, a função strlen () pode se parecer com isto”, em um ( talvez mais simples?) forma poderia ser semelhante a:
int strlen(const char *data) { const char *p = data; while (*p++); return p-data-1; }
- @ jwpat7 Eu disse " mais simples ", não " mais curto e compacto ". Essa forma, embora menor e mais eficiente, é muito mais difícil para o OP (que obviamente não um programador) entender.
- Concordo 🙂 Também é mais fácil cometer erros em . E se
\0
for o último byte acessível em um segmento, o*p++
falhará. Masint strlen(const char *data) { const char *p = data; while (*p) ++p; return p-data; }
evita esse problema. - Na verdade,
*p++
ganhou ' t falha mesmo se\0
for o último byte acessível em um segmento; a parte*p
acessará o último byte; a parte ++ definiráp
para um endereço inválido; mas como esse endereço inválido não ' é referenciado, em uma máquina típica nenhuma falha ocorre. - É uma macro em tempo de compilação … ' não é uma macro , é ' é um operador (como " + " e " – " são operadores). Eles são de nível inferior que as macros, que são coisas feitas no tempo do pré-processador. Consulte operador sizeof . Além disso, Operadores em C ++
Resposta
use sizeof char nnn[10]; for(int i=0; i< sizeof(nnn)/sizeof(char); i++){ }
Comentários
- Você leu a pergunta corretamente?
- O OP disse
sizeof
" não ' não funciona para mim " e então você sugere o uso do sizeof. - não posso responder à pergunta ao usar o mesmo desconhecido
char foo [100] = "bar";
– é isso que você quer dizer? Você quer a resposta: 3?