Я не совсем уверен, что вы спрашиваете. Вы спрашиваете, как программа смогла правильно прочитать word4
из файла, даже если за ним не было пробела? Или вы спрашиваете, почему, когда программа выводила word4
назад, после нее, казалось, не было пробела?
Ответ на первый вопрос заключается в том, что strtok
предназначен для предоставления вам токенов , разделенных разделителями, а не , оканчивающимися разделителями. Не требуется, чтобы за последним токеном следовал разделитель.
Чтобы увидеть ответ на второй вопрос, может быть более понятным, если мы немного скорректируем программу и ее распечатку:
char* word = strtok(line, " ");
for (int i = 0; word != NULL; i++) {
printf("%d: \"%s\"\n", i, word);
word = strtok(NULL, " ");
}
Я сделал два изменения здесь:
- Цикл выполняется до тех пор, пока
word
не станет NULL, то есть, пока strtok
не найдет другое слово в строке. (Это делается для того, чтобы убедиться, что мы видим все слова, и чтобы мы не пытались обрабатывать четвертое слово специально каким-либо образом. Если вы были , пытаясь обработать четвертое слово специально каким-то образом, скажите, пожалуйста.)
- Слова выводятся обратно в окружении кавычек, чтобы мы могли точно видеть, что они содержат.
Когда я запускаю измененную программу, я вижу:
0: "word1"
1: "word2"
2: "word3"
3: "word4
"
Эта последняя строка поначалу выглядит очень странно, но объяснение простое. Изначально вы читаете строку, используя fgets
, который копирует завершающий символ \n
в буфер line
. Таким образом, в итоге он остается прикрепленным к word4
; то есть четвертое «слово» - "word4\n"
.
По этой причине часто хорошей идеей является включение \n
в набор символов разделителей пробелов, которые вы передаете strtok
- то есть вместо этого вы можете вызвать strtok(line, " \n")
. Если я сделаю это (в обоих вызовах strtok
), выход изменится на
0: "word1"
1: "word2"
2: "word3"
3: "word4"
, что может быть ближе к тому, что вы ожидали.