2015-07-12 20 views
6

Czytam ze słownika i wypisuję słowo + długość słowa do celów testowych.strlen nie podając prawidłowej długości napisu C

Używam strlen, aby uzyskać długość struny. Jednak liczby, które otrzymałem, są nieprawidłowe. Wierzę, że strlen nie zalicza znaku \ 0.

Czytam pierwsze 10 słów ze słownika. My spodziewać wyjście powinno być:

W:A L:1 
W:A's L:3 
W:AA's L:4 
W:AB's L:4 
W:ABM's L:5 
W:AC's L:4 
W:ACTH's L:6 
W:AI's L:3 
W:AIDS's L:6 
W:AM's L:4 

Ale to co mam (Zauważ, że L:. 'S są na innej linii myślę, że to jest, gdzie jest problem):

W:A 
L:2 
W:A's 
L:4 
W:AA's 
L:5 
W:AB's 
L:5 
W:ABM's 
L:6 
W:AC's 
L:5 
W:ACTH's 
L:7 
W:AI's 
L:5 
W:AIDS's 
L:7 
W:AM's 
L:5 

Poniżej to mój kod:

FILE* dict = fopen("/usr/share/dict/words", "r"); //open the dictionary for read-only access 
    if(dict == NULL) { 
     return; 
    } 

    int i; 
    i = 0; 

    // Read each line of the file, and insert the word in hash table 
    char word[128]; 
    while(i < 10 && fgets(word, sizeof(word), dict) != NULL) { 
     printf("W:%s L:%d\n", word, (int)strlen(word)); 

     i++; 
    } 
+2

Wynik 'fgets()' często zawiera '' \ n''. Aby przyciąć, zobacz http://stackoverflow.com/a/28462221/2410359 BTW, ładnie sformułowane pytanie, choć z pewnością duplikat. – chux

+1

"Wierzę, że' strlen' nie zalicza znaku '\ 0''. - Nie, tak nie jest i nie powinno. (Dowolne odwołanie do funkcji 'strlen', w tym' man strlen', jeśli twój system ma strony podręcznika, powiedziałoby ci to.) –

Odpowiedz

7

fgets() wczytuje nowy wiersz do bufora, jeśli jest wystarczająco dużo miejsca. W rezultacie zobaczysz znak nowej linii po wydrukowaniu word. Z instrukcji fgets:

fgets() odczytuje co najwyżej jeden mniej niż size znaków ze strumienia i zapisuje je do bufora wskazywanego przez s. Czytanie zatrzymuje się po EOF lub nowej linii. Jeśli zostanie odczytany znak nowego wiersza, zostanie on zapisany w buforze . Końcowy bajt zerowy ("\ 0") jest przechowywany po ostatnim znaku w buforze.

(Kopalnia nacisk)

trzeba go przyciąć sobie pytanie:

while(i < 10 && fgets(word, sizeof(word), dict) != NULL) { 
    size_t len = strlen(word); 
    if (len > 0 && word[len-1] == '\n') word[len] = '\0'; 

    printf("W:%s L:%d\n", word, (int)strlen(word)); 
    i++; 
} 
4

Powodem jest fakt fgets ciągnie znak nowej linii '\ n' w swoim buforze word każdym razem , co prowadzi do zwiększenia liczby o 1 za każdym razem.

+1

Kiedy czytany jest ostatni wiersz w pliku, nie jest niezamieszane, aby _nie_ mieć tailinga '' \ n''. Zatem 'fgets()' nie zawsze przyciąga '\ n''. – chux

+0

, więc 'fgets()' nie ciągnie '\ n'' jeśli znak nowej linii istnieje, tak jak powiedziałem. Oczywiście, jeśli dokument nie ma znaku nowej linii, fgets go nie wygeneruje. –

+0

również, jeśli nie masz wystarczająco dużo miejsca w buforze, aby uwzględnić znak nowej linii, otrzymasz go przy następnym 'fgets()'. –