Ce fel de funcție pot folosi pentru a ști câte elemente sunt într-o matrice de caractere?
sizeof () oferă numărul de „spații” disponibile, așa că nu funcționează pentru mine.
Comentarii
Răspuns
Vrei strlen
.
char foo [100] = "bar"; Serial.println (strlen (foo)); // --> prints 3
Comentarii
- Dacă răspunsul a funcționat pentru dvs., vă rugăm să faceți clic pe butonul " acceptați " (arată ca o căpușă). Astfel, alte persoane vor ști că soluția a funcționat.
- A trebuit să aștept câteva minute pentru a face acest lucru.
- Rețineți că acest lucru va funcționa numai dacă datele din conține un șir ascii și este terminat corect. Mai mult, dacă aveți un șir lung în
char[]
și îl suprascrieți cu un șir mai scurt, fără a adăuga terminarea nulă, veți obține dimensiunea șirului mai vechi. - Foarte bine. Răspunsul meu a fost pentru întrebarea prezentată. Lucrurile pe care le menționați trebuie luate în considerare pentru șirurile C. terminate cu nul.
Răspuns
Vă cunosc primiți răspunsul dvs. de la @ NickGammon, dar aș vrea să adaug informații mai detaliate despre cum funcționează toate acestea.
sizeof()
nu este funcționează în sensul normal al cuvântului. Este un operator care vă oferă numărul de octeți de memorie alocați oricărui lucru pe care îl transmiteți. Dacă îi treceți o matrice, acesta returnează numărul de octeți pe care matricea îi are la dispoziție. Dacă îl trimiți un pointer către un tablou, acesta returnează dimensiunea acelui pointer, nu dimensiunea tabloului. Dacă îi trimiți o variabilă întreagă, returnează numărul de octeți folosiți de acea variabilă întreagă (2 pe un 8-bit ca AVR, 4 pe un sistem pe 32 de biți precum Due).
Deci câteva exemple:
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
Acum strlen()
. Cum diferă exact acest lucru de sizeof()
? Pur și simplu, numără numărul de caractere dintr-o matrice de caractere până ajunge la caracterul \0
care este caracterul de terminare” NULL „al unui șir C. Să luăm exemplele înainte, dar să folosim în schimb strlen:
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ți că returnează întotdeauna numărul de caractere din șir până la, dar fără a include, caracterul \0
final.
În forma sa cea mai simplă, funcția strlen()
ar putea arăta astfel:
int strlen(const char *data) { int c = 0; const char *p = data; while (*p) { c++; p++; } return c; }
Practic începe de la primul caracter din șir (*p = data
), examinează dacă este „sa \0
sau nu (while (*p)
), crește numărul de caractere (c++
) și trece la următorul caracter în șir (p++
).
Dacă doriți să parcurgeți șirul în programul dvs., puteți apela strlen()
mai întâi pentru a obține numărul de caractere din șir, apoi utilizați acea valoare într-o buclă. Acest lucru este puțin risipitor, deoarece strlen()
iteră mai întâi prin șir, astfel încât să ajungeți să iterați prin el de două ori. Este mult mai eficient să aflați cum să parcurgeți cel mai bine fiecare caracter din șir până când găsiți caracterul care se termină, cum ar fi modul în care funcția strlen()
folosește indicatorul pentru a vă deplasa prin memorie. De asemenea, puteți vedea cât de vital este să vă asigurați că caracterul \0
există la sfârșitul șirului, altfel cum vor funcționa ca strlen()
știi când să te oprești? Ei nu pot să știe cât este șirul (sizeof()
va returna dimensiunea indicatorului pe care este trecut, nu dimensiunea matricei), deci trebuie să aibă un fel de manual, iar convenția din C este de a utiliza \0
.
Rețineți că funcțiile Arduino „s print()
fă-o foarte ineficient. Dacă faceți ceva de genul:
char message[] = "Hello"; Serial.println(message);
De fapt, va face o mulțime de muncă pe care nu trebuie să o faceți. pas cu pas:
- apelează println (mesaj)
- care apelează write (mesaj)
- care obține lungimea șirului cu strlen (mesaj)
- și apeluri de scriere (mesaj, lungime)
- care apoi trece de la 0 la lungime-1 trimitând pe rând fiecare caracter al mesajului pentru a scrie ().
- imprimă în cele din urmă
\r\n
pentru noua linie.
Deci se termină cuibărit în jurul a 4 funcții adâncime și iterează întregul șir de două ori. A exemplu clasic despre cum să pierdeți timpul de procesare.Iterând prin șir odată căutând caracterul \0
în funcția write(message)
(pasul 2) ar funcționa cel puțin de două ori mai repede. Bine vechi Arduino …
Comentarii
- Re „În forma sa cea mai simplă funcția strlen () ar putea arăta astfel” poate mai simplu?) forma ar putea arăta astfel:
int strlen(const char *data) { const char *p = data; while (*p++); return p-data-1; }
- @ jwpat7 Am spus " cel mai simplu ", nu " cel mai scurt și mai compact ". Această formă, deși este mai mică și mai eficientă, este mult mai greu de înțeles de către OP (care, în mod evident, nu este un programator).
- De acord 🙂 De asemenea, este mai ușor să greșești în . Și dacă
\0
este ultimul octet accesibil dintr-un segment,*p++
se va defecta. Darint strlen(const char *data) { const char *p = data; while (*p) ++p; return p-data; }
evită această problemă. - De fapt,
*p++
a câștigat ' vina chiar dacă\0
este ultimul octet accesibil dintr-un segment; partea*p
va accesa ultimul octet; partea ++ va setap
la o adresă nevalidă; dar, deoarece acea adresă nevalidă ' nu poate fi menționată, pe o mașină tipică nu apare nicio defecțiune. - Este o macro de compilare … Nu ' nu este o macro , este ' este un operator (cum ar fi " + " și " – " sunt operatori). Acestea sunt de nivel mai mic decât macro-urile, care sunt lucruri făcute în timpul pre-procesorului. Consultați sizeof operator . De asemenea, Operatori în C ++
Răspuns
use sizeof char nnn[10]; for(int i=0; i< sizeof(nnn)/sizeof(char); i++){ }
Comentarii
- Ați citit corect întrebarea?
- OP a spus
sizeof
" nu funcționează pentru mine " și apoi sugerați să folosiți sizeof. - nu; nu puteți răspunde la întrebare atunci când utilizați același necunoscut
char foo [100] = "bar";
– la asta te referi? Vrei răspunsul: 3?