Изучение функции getchar()

Меня интересует C, поэтому я хочу больше узнать о C, особенно о C89, чтобы увидеть, как этот язык изменился с течением времени :). Я купил "Язык программирования C" (2-е издание) Дениса Ритчи.

Пример из книги приводит меня к сложной ситуации с функцией getchar().

Пример 1, который является моим примером после прочтения книги:

#include <stdio.h>

int main()
{
    int c = getchar();
    printf("\'\\n\' character in c: %d\n", c == '\n');
    printf("\'\\n\' character in c: %d\n", c == '\n');
}

Результат примера 1:

a
'\n' character in c: 0
'\n' character in c: 0

В этом случае вывод не показывает никаких новых символов строк в этом вводе. ОДНАКО, еще один пример, который я пробую:

#include <stdio.h>

int main()
{
    int c;

    while ((c = getchar()) != EOF) {
        printf("\'\\n\' character in c: %d\n", c == '\n');
    }
}

и вывод кода:

a
'\n' character in c: 0
'\n' character in c: 1

Я не понимаю, почему второй пример дублирует функцию printf() и как она могла прочитать символ '\n' при входе в цикл. Между тем, первый пример не показывает ничего, относящегося к символу '\n'

Это связано с входным потоком; /n все еще остается во входном потоке после первого вызова.

Isaiah 01.03.2019 14:51

В первом коде вы просто дважды проверяете этот a, а во втором коде проверяется a, а затем \n.

Blaze 01.03.2019 14:52

Мистер @Blaze, не могли бы вы объяснить мне, как работает память в обеих ситуациях? Спасибо

Huy Vũ 01.03.2019 14:54

Ответ Лундина прекрасно это объясняет. Причина, по которой он не проверяет \n в первом примере, заключается в том, что вы не говорите ему об этом. int c = getchar(); переводит a в c, а затем вы проверяете это дважды. Вы никогда этого не читали \n. Вы, наверное, хотели еще один c = getchar(); после первого отпечатка.

Blaze 01.03.2019 14:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
78
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы нажимаете ввод после ввода a.

Таким образом, ваш входной поток будет иметь «a\n».

while ((c = getchar()) != EOF) {

Будет читать, пока не достигнет EOF, поэтому сначала будет читать a, а затем \n(введите).

  • Вы вводите a и нажимаете ввод. Буфер стандартного ввода будет выглядеть как a, \n, два символа.
  • Первый круг в цикле, c имеет значение 'a', которое не равно '\n', выход 0.
  • Следующий круг в цикле c имеет значение '\n', равное '\n', выход 1.
  • В конце ввода, когда c становится EOF, printf никогда не выполняется.

Спасибо. Но почему в первом примере не проверяется символ '\n'?

Huy Vũ 01.03.2019 14:56

Это не потому, что вы запрашиваете символ только один раз. getchar() возвращает по одному символу за раз, а все оставшиеся символы остаются во входной строке для использования последующими вызовами getchar.

Isaiah 01.03.2019 14:58
Ответ принят как подходящий

Возьмем ваш второй пример, т.е.

while ((c = getchar()) != EOF) {
    printf("\'\\n\' character in c: %d\n", c == '\n');
}

и развернуть петлю. Это станет:

c = getchar();
if (c == EOF) return 0;
printf("\'\\n\' character in c: %d\n", c == '\n');
c = getchar();
if (c == EOF) return 0;
printf("\'\\n\' character in c: %d\n", c == '\n');
c = getchar();
if (c == EOF) return 0;
printf("\'\\n\' character in c: %d\n", c == '\n');
... and so on ...

Теперь сравните это с вашей первой версией, и вы увидите, что разница в том, что второй пример делает вызов getchar между printf, в то время как в первом примере есть только один вызов getchar.

Другими словами, в первом примере читается только символ 'a', а во втором примере сначала читается 'a', затем читается '\n', а затем читается .... (независимо от того, что вы наберете дальше)

Другие вопросы по теме