Понимание ungetc использовать в простом getword
Я сталкивался с таким примером getword. Я понимаю все проверки и т. Д., Но у меня есть проблема с ungetc.
Когда c
удовлетворяет if ((!isalpha(c)) || c == EOF)
а также не удовлетворяет while (isalnum(c))
-> это не буква и не число - ungetc
отвергает это char
,
Давайте предположим, что это '\n'
,
Тогда дело доходит до return word
однако он не может быть возвращен, так как он не сохранен ни в одном массиве. Что происходит потом?
while (isalnum(c)) {
if (cur >= size) {
size += buf;
word = realloc(word, sizeof(char) * size);
}
word[cur] = c;
cur++;
c = fgetc(fp);
}
if ((!isalpha(c)) || c == EOF) {
ungetc(c, fp);
}
return word;
РЕДАКТИРОВАТЬ@Mark Byers - спасибо, но что c был отклонен с какой-то целью, и не будет выполнять условие снова и снова в бесконечном цикле?
3 ответа
Состояние терминала прямо перед линией, которую вы не понимаете, не очень хорошее. Вероятно, должно быть:
int c;
...
if (!isalpha(c) && c != EOF)
ungetc(c, fp);
Это означает, что если последний прочитанный символ был реальным символом (не EOF) и не был буквенным символом, отодвиньте его обратно для повторной обработки любым последующим использованием входного потока fp
, То есть предположим, что вы читаете пустое место; пробел завершит цикл, и пробел будет сдвинут назад так, чтобы следующий getc(fp)
будет читать бланк снова (как бы fscanf()
или же fread()
или любая другая операция чтения в файловом потоке fp
). Если вместо пустого вы получили EOF, то в моем пересмотренном коде нет попытки отодвинуть EOF; в исходном коде EOF будет отброшен назад.
Обратите внимание, что c
должен быть int
а не char
,
ungetc
помещает символы в поток, чтобы при следующем чтении этот символ снова возвращался.
ungetc(c, fp); /* Push the character c onto the stream. */
/* ...etc... */
c = fgetc(fp); /* Reads the same value again. */
Иногда это может быть удобно, если вы читаете символы, чтобы узнать, когда текущий токен завершен, но еще не готовы прочитать следующий токен.
ХОРОШО. Теперь я понимаю, почему это, например, с. '\n'
беспокоил меня. Я просто тупой и забыл про раздел в main()
ссылаясь на getword. Конечно, перед вызовом getword есть пара тестов (еще один ungetc
там) и это fputs
что персонажи не удовлетворяют isalnum
Из этого вытекает, что while
зациклиться getword
всегда начинается хотя бы с одного isalnum
положительный, и проверка в конце означает только следующие символы.