2015-07-12 2 views
6

Я читаю из своего словаря и печатаю слово + длину слова для целей тестирования.strlen не дает правильной длины строки C

Я использую strlen для получения длины строки. Однако числа, которые я получил, неверны. Я считаю, что strlen не считает символ \ 0.

Я читаю первые 10 слов в словаре. Мой ожидаемый результат должен быть:

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 

Но это то, что я получил (Обратите внимание, как L:. 'S находятся на другой линии, я думаю, что это где проблема):

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 

Ниже мой код:

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

Результат 'fgets()' часто включает '' \ n''. Чтобы обрезать, см. Http://stackoverflow.com/a/28462221/2410359 Кстати, хорошо сформированный вопрос, хотя, безусловно, дубликат. – chux

+1

«Я считаю, что' strlen' не учитывает символ '' \ 0''. - Нет, этого нет, и это не так. (Любая ссылка на функцию 'strlen', в том числе' man strlen', если ваша система имеет man-страницы, сообщит вам об этом.) –

ответ

7

fgets() читает символ новой строки в буфер, если есть достаточно места. В результате вы увидите новую строку, напечатанную при печати word. Из инструкции fgets:

fgets() считывает максимум один меньше символов размера из потока и сохраняют их в буфер, на который указует с. Чтение останавливается после EOF или новой строки. Если прочитана новая строка, она сохраняется в буфере . Конечный нулевой байт ('\ 0') сохраняется после последнего символа в буфере.

(курсив мой)

Вы должны подрезать сами:

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

Причина в том, что fgets тянет символ новой строки '\ п' в буфере word каждый раз , что приводит к увеличению счетчика на 1 каждый раз.

+1

Когда прочитана последняя строка в файле, она не является uncomon для _not_ иметь хвост ' \ n''. Поэтому 'fgets()' не всегда вытягивает '' \ n''. – chux

+0

поэтому 'fgets()' делает в '' \ n'', если символ новой строки существует, как я уже сказал. Очевидно, что если у документа нет символа новой строки, fgets не будет генерировать его. –

+0

также, если в буфере недостаточно места для включения новой строки, вы получите его на следующем 'fgets()'. –

Смежные вопросы