(Упражнение 1.6 K&R) Как проверить, что getchar() != EOF ЕСТЬ 0 ИЛИ 1?

Я только начал изучать программирование (C) в качестве хобби, самостоятельно. Я использую K&R.

 main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}

Убедитесь, что getchar() != EOF ЕСТЬ 0 ИЛИ 1

Кажется, я понимаю, что происходит:

  1. c назначается следующий символ с клавиатуры
  2. c проверяется, является ли он EOF или нет
  3. c присваивается 1 или 0, в зависимости от того, EOF это или нет.
  4. символ отображается на выходе или если EOF завершает программу.

Однако мое решение неверно, поэтому я явно чего-то не понимаю:

main ()
{
    int c;

    while ((c = getchar()) != EOF)
        printf("%d\n", c);
}

Это просто печатает значение символа. А также печатает «10», если я нажимаю клавишу возврата каретки.

Я думал, что он напечатает c. Однако он печатает значение символа, а не значение 1 или 0.

Я знаю, что c присваивается 1 или 0 после сравнения с EOF. Но я не уверен, какую логику я могу использовать, чтобы показать это. Кажется, мне нужно как-то «выйти» из отображения значения символа и вместо этого показать значение сравнения. Означает ли это, что мне нужно выйти из цикла while? Если да, то я не знаю как (и это только предположение).

Как я могу просто проверить, что c = 1 или 0?

Кроме того, откуда мне это знать? Полагаю, должно быть что-то фундаментальное, что я должен извлечь из этого.

main ()
{
    int c;

    while ((c = getchar()) != EOF != 0 != 1)
        putchar(c);
}

Я также сделал это, и я думаю, что это работает. Поскольку он не выводит никаких символов, но я не уверен, что это решение, которое они ищут...


person BBedit    schedule 19.07.2013    source источник
comment
x != y возвращает логическое значение. Вы можете убедиться, что это всегда 1 или 0, прочитав стандарт C (и предполагая, что ваш компилятор действительно следует ему, я полагаю). значение сравнения с EOF).   -  person Wooble    schedule 19.07.2013


Ответы (8)


Я знаю, что c присваивается 1 или 0 после сравнения с EOF

Нет, это не так. Смотреть:

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

Это выражение: (c = getchar()) != EOF, которое содержит другое выражение: (c = getchar()), которое присваивает c символ с клавиатуры. c не будет равно 0 или 1! Это результат выражения. Попробуйте этот код:

int main()
{
   char value;
   int c;
   value = ((c = getchar()) != EOF);
   printf("%i\n", value);
   return 0;
}

Этот код напечатает значение выражения (c = getchar()) != EOF. На самом деле, ваш код может быть написан так:

int main ()
{
    int c;
    char value = ((c = getchar()) != EOF);
    while (value)
    {
        printf("%d\n", c);
        value = ((c = getchar()) != EOF);
    }
    return 0;
}

Выражение больше не находится в while, и его результат присваивается value. Приведенный выше код и ваш код будут давать точно такой же результат.


ИЗМЕНИТЬ:

main ()
{
    int c;

    while ((c = getchar()) != EOF != 0 != 1)
        putchar(c);
}

Приведенный выше код не является решением! Вот переписанный код:

main ()
{
    int c;
    char value1;
    char value2;
    char value3;

    value1 = ((c = getchar()) != EOF);
    value2 = value1 != 0;
    value3 = value2 != 1;
    while (value3)
    {
        putchar(c);
        value1 = ((c = getchar()) != EOF);
        value2 = value1 != 0;
        value3 = value2 != 1;
    }
}

Так что же происходит? Допустим, getchar вернет символ «A». Это означает, что:

  • value1 будет равно 1, так как 'A' отличается от EOF.
  • value2 будет равно 1, потому что value1 (равное 1) отличается от 0.
  • value3 будет равно 0, потому что value2 (равное 1) не отличается от 1: while(value3) теперь равно while(0), поэтому никакие символы не будут напечатаны.

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


Несколько слов о комментарии ОП:

Эй, спасибо. Но K&R прямо говорит, что установка c на 1 или 0 приводит к нежелательному эффекту. Может быть, поэтому я запутался.

c будет присвоено значение 0 или 1, если while выглядит так:

while (c = getchar() != EOF)

Оператор != имеет больший приоритет, чем оператор =. Это означает, что сначала будет оцениваться getchar() != EOF, а затем его результат будет присвоен c.

person nouney    schedule 19.07.2013
comment
Эй, спасибо. Но K&R прямо говорит, что установка c на 1 или 0 приводит к нежелательному эффекту. Может быть, поэтому я запутался. - person BBedit; 19.07.2013
comment
Я начинаю чувствовать, что программирование не для меня. Кажется слишком сложным понять даже эти простые понятия. Спасибо за ваши объяснения! - person BBedit; 19.07.2013
comment
@user2071506 user2071506 Ах да ладно :) Это совершенно нормально! На самом деле K&R не предназначен для начинающих. Это одна из лучших книг, но она предполагает, что у вас уже есть некоторый опыт программирования. Язык C не самый простой язык для изучения программирования, но если вы его знаете, вы можете знать все ;) - person nouney; 19.07.2013
comment
Примечание. c может принимать значение 0 или 1, так как многие клавиатуры допускают ввод, например Ctrl-@ или Ctrl A, которые сопоставляются с 0 и 1. - person chux - Reinstate Monica; 25.03.2015

Я понимаю, что вопрос устарел, но выбранный ответ отвечает на что-то, что не соответствует тому, что вопрос должен быть задан. (Это другой вопрос, заданный в книге). Я здесь, чтобы прояснить несколько вещей и надеюсь, что другие люди, которые искали этот вопрос в Google, смогут прочитать мой ответ для лучшего понимания вопроса 1-6 из The C Programming Language 2nd. Версия.

В вопросе говорилось проверьте, что getchar() != EOF IS 0 OR 1

Книга намекнула, что

**c = (getchar() != EOF)**

эквивалентно

**c = getchar() != EOF**

Когда getchar() != EOF тестируется,

Если ввод не EOF, то он должен быть истинным, поэтому возвращается True или 1 в этом смысле.

И, конечно же, если ввод равен EOF, то getchar() != EOF вернет False или 0.

Поэтому либо 1, либо 0 будут присвоены c.

Для "нежелательного эффекта", упомянутого в книге, поскольку ни 1, ни 0 не являются исходными входными данными, это означает, что исходный символ, предназначенный для вывода, потерян, а это нежелательно.

Для упражнения используйте это:

#include <stdio.h>

main()
{
    int c;
    while ( c = getchar() != EOF ) {
        printf("%d\n", c);
    }
}

Если ваш ввод не EOF, то будет напечатано 1.

Если ваш ввод EOF, то программа завершается.

ПРИМЕЧАНИЕ. Чтобы ввести EOF в Windows, используйте Ctrl + Z

Изменить:

Более простое решение упражнения 1.6 K&R.

printf("%d", getchar() != EOF);
person Sayyora    schedule 24.01.2015

'c' присваивается значение из getchar, а затем проверяется, является ли оно EOF.

Если он не назначен EOF, выведите значение 'c'; если нет, существует петля.

тест для EOF не переназначает какое-либо значение 'c', он только успешен или терпит неудачу

IOW, удалите свой шаг 3.

person KevinDTimm    schedule 19.07.2013

Здесь c не присваивается результату сравнения. Он содержит value read form File.

Для проверки результата сравнения необходимо следующее

int результат = ((c = getchar()) != EOF)

Затем используйте результат, чтобы проверить, является ли он 0 или 1.

printf("%d",result);
person pradipta    schedule 19.07.2013

У меня было много проблем с этой самой проблемой.

А также печатает «10», если я нажимаю клавишу возврата каретки.

Кроме того, на странице 20 K&R указано, что значение ASCII для '\n' равно 10. Так что, возможно, вы возвращаете это значение непреднамеренно?

Каждый раз, когда я возвращаюсь к этому, я забываю, что клавиша возврата каретки НЕ ЯВЛЯЕТСЯ EOF.

Как указывает пользователь Sayyora выше, вам нужна комбинация клавиш, чтобы сигнализировать об окончании операции.

Для линукса это:

Ctrl + Д

Кроме того, чтобы убить программу (по крайней мере, в X-Term), это:

Ctrl + С

person VonRansak    schedule 27.12.2015

Я использую исходный файл C в DevC++ 4.9.9.2. Я новичок в программировании на C и использую K/R 2nd Ed. в качестве моего гида. После просмотра утверждений, приведенных выше, я обнаружил, что следующие строки дают мне желаемый результат в примере 1.6/1.7. Не стесняйтесь исправлять мое понимание, но, воспользовавшись советом автора(ов) об использовании скобок и печати как внутри, так и вне цикла while, можно получить результат 1 или 0. Последний getchar() требование среды Dev-C держать экран ввода/вывода открытым для просмотра распечатанных отчетов.

main()
{
      int c; 
      while (c=getchar() !=EOF)
            printf("%d",c);
      printf("%d",c);
      getchar();      
person Brian Dresser    schedule 09.09.2016

#include <stdio.h>
   
int main(){
    int c;
    printf("Verifying that the expression 'c = getchar() != EOF' is: %d \n", (getchar() != EOF));
   
    return 0;
}

Что ж, когда вы вводите значение в «c», это !=, поэтому он возвращает «1», а когда вы отправляете команду EOF, он возвращает «0».

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

person Anton Dutsov    schedule 16.03.2021

person    schedule
comment
Вы представляете решение для заведомо начинающего программиста. В идеале это должно сопровождаться подробным объяснением. - person sorak; 28.02.2018
comment
Вызов getchar(c) использует один символ. Так как же вывести каждый getchar(c), а также значение EOF для одного и того же вызова getchar(c)? Один из способов — вызвать getchar(c) в самой функции printf(). Это позволяет вам вызывать getchar() один раз для каждого введенного символа при печати результирующего char и EOF. Предложение в операторе while допускает это, но это не очень элегантно. Я не уверен, позволят ли это более поздние версии C, но ANSI C позволяет. Для компиляции с ANSI используйте флаг -ansi. - person tedro; 28.02.2018
comment
только что понял, что последний char в getchar() - это char(10), поэтому он невидим, но putchar(c) обрабатывает его как любой другой char - person tedro; 01.03.2018