2015-07-12 22 views
6

Sto leggendo dal mio dizionario e stampando la parola + la lunghezza della parola a scopo di test.strlen che non fornisce la lunghezza corretta della stringa C

Io uso strlen per ottenere la lunghezza della stringa. Tuttavia, i numeri che ho ricevuto non sono corretti. Credo che strlen non contenga il carattere \ 0.

Sto leggendo le prime 10 parole nel dizionario. Il mio risultato atteso dovrebbe essere:

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 

Ma questo è quello che ho ottenuto (Si noti come la L:. 'S sono su un'altra linea Penso che questo è dove il problema è):

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 

Sotto è il mio codice:

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

Il risultato di 'fgets()' include spesso ''\ n''. Per tagliare, vedi http://stackoverflow.com/a/28462221/2410359 BTW, domanda ben formata, anche se certamente un duplicato. – chux

+1

"Credo che' strlen' non contenga il carattere ''\ 0''." - No, non è così, e non dovrebbe. (Qualsiasi riferimento alla funzione 'strlen', incluso' man strlen' se il tuo sistema ha pagine man, te lo direbbe.) –

risposta

7

fgets() legge nel newline nel buffer se c'è abbastanza spazio. Di conseguenza, si vede stampato il newline quando si stampa word. Dal manuale fgets:

fgets() legge in al più una meno di caratteri di dimensioni dal flusso e li memorizza nel buffer puntato da s. La lettura si interrompe dopo un EOF o una nuova riga. Se una nuova riga viene letta, viene archiviata nel buffer . Un byte null terminante ('\ 0') viene memorizzato dopo l'ultimo carattere nel buffer.

(sottolineatura mia)

Dovete tagliare da soli:

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

Il motivo è perché fgets tira il carattere di nuova linea '\ n' nel buffer word ogni volta , portando ad un conteggio superiore di 1 ogni volta.

+1

Quando l'ultima riga in un file viene letta, non è comune a _non_ avere un tailing '' \ n''. Quindi 'fgets()' non inserisce sempre un ''\ n''. – chux

+0

così 'fgets()' inserisce un ''\ n'' se il carattere di nuova riga esiste, come ho detto. Ovviamente se il documento non ha un carattere di nuova riga, fgets non ne genererà uno. –

+0

Inoltre, se non si dispone di spazio sufficiente nel buffer per includere la nuova riga, lo si otterrà al prossimo 'fgets()'. –

Problemi correlati