Разница между назначением int для getchar() и использованием getchar() без него

Выполняя упражнение в книге K&R (язык программирования C, 2-е издание), я столкнулся с проблемой, которую, похоже, не понимаю и не понимаю. А именно, упражнение заключалось в написании программы, которая подсчитывает пробелы, табуляции и новые строки (в самом начале книги). Я пишу в Debian/ Gedit(не знаю, если это актуально).

Код, который я написал:

#include <stdio.h>

int main(void)

{

int nb = 0;         
int nt = 0;         
int nl = 0;         

while(getchar() != EOF)

    {
    if(getchar() == ' ')
        ++nb;
    if(getchar() == '\t')
        ++nt;
    if(getchar() == '\n') 
        ++nl;
    }
printf("%d\n%d\n%d\n", nb, nt, nl);

return 0;
}

Теперь, когда я выполняю программу, она не считает пробелы или табуляции и в целом не ведет себя так, как задумано.

Затем я проверил правильный ответ в книгах и увидел, что они имеют, а int c назначен getchar(), а именно

while((c = getchar()) != EOF)
    if(c == ' ')
     ++nb;

и так далее.

Теперь я не понимаю, почему так важно присвоить int в этом случае c для getchar() и использовать его в скобках IF. Должен ли способ, которым я написал это, не работать так же?

Теперь, как я понимаю, int c не является определенным значением или точным значением, поэтому для меня, как для новичка, все это выглядит как единственная цель его назначения, поэтому нам не нужно каждый раз писать getchar() и мы можем просто написать c.

Также есть ли конкретное желаемое условие, когда вы должны или не должны присваивать int для getchar()?

Выполнение кода, как они написали, дает ожидаемый результат, но, честно говоря, я не понимаю, что на самом деле здесь происходит.

Любая помощь приветствуется, и спасибо заранее.

4 ответа

Решение

Теперь я не понимаю, почему так важно присвоить int в этом случае c для getchar() и использовать его в скобках IF.

Это действительно важно назначить c в getchar,

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

на самом деле это три шага:

  • getchar() получить символ из стандартного потока ввода (stdin).
  • Символ чтения затем присваивается c,
  • затем c по сравнению с EOF,

Должен ли способ, которым я написал это, не работать так же?

while(getchar() != EOF)

    {
    if(getchar() == ' ')
        ++nb;

Нет. Ваш код не имеет ожидаемого поведения, потому что вы звоните getchar несколько раз внутри вашего while петля. Что на самом деле делает ваш код:

  • Прочитать первый символ из стандартного ввода stdin,
  • Сравните этот первый символ с EOF.
  • Тогда, если это НЕ EOF, прочитайте второй символ от stdin.
  • Сравните второй символ с ' ',
  • И так далее.

Вы можете понять, почему это не ожидаемое поведение, потому что вам нужно прочитать один символ и сравнить его со всеми значениями.

Это потому, что каждый getchar() Вызов читает другой символ из ввода. Таким образом, вы не сможете использовать его позже для проверки пробелов.

что я не понимаю, так это почему важно назначить int в этом случае c для getchar() и чем использовать его в скобках IF. Должен ли способ, которым я написал это, не работать так же?

Вам необходимо присвоить переменную, потому что вы хотите использовать ее позже. То, как вы написали, не сработает для проблемы, которую вы пытаетесь решить.

Также есть ли конкретное желаемое условие, когда вы должны или не должны присваивать int для getchar()?

Нет. Нет правила, назначать или нет. Это зависит от конкретной проблемы, которую вы решаете. Вы должны назначить, если вы хотите использовать / проверить значение позже.

Например, если вы просто хотите игнорировать пробелы, то:

int c = gethchar();
getchar(); // Simply discard one character from inout

Ты звонишь getchar() неоднократно в каждом if тестовое задание.

Вы пропустите много потенциальных совпадений при каждом вызове getchar потребляет другой символ из входного буфера.

Вы должны назначить возврат getchar() переменной, один раз за цикл, и проверьте это. while((c = getchar()) != EOF) будет хорошо работать для этого, и тест для c в теле цикла.

Теперь я не понимаю, почему так важно присвоить int в этом случае c для getchar() и использовать его в скобках IF. Должен ли способ, которым я написал это, не работать так же?

Прежде всего здесь c не назначен getchar() скорее getchar() назначен на c,

Двигаясь дальше, мы просто сохраняем символ, прочитанный getchar() в c проверить, является ли введенный символ (пробел) или \n или что-то в следующем коде.

По словам man getchar

getchar() возвращает символ, прочитанный как символ без знака, приведенный к int или EOF в конце файла или ошибки.


Если мы не сохранили символ, прочитанный getchar() в c и использовал отдельный getchar() вызовы функций в последующем коде, то мы теряем то, что getchar() читать в начале, а также в других getchar() звонки.

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