Проблема с примером 1.5.2 в книге K & R на C - PullRequest
5 голосов
/ 05 сентября 2010

Я учу себя C с K & R, и я озадачен одним из примеров в книге.Я компилирую код в точности так, как он написан в примере, но он не выполняет то, что говорят авторы.Программа должна рассчитывать символы.Данный код выглядит следующим образом:

#include <stdio.h>

/* count characters in input; 1st version */
main()
{
    long nc;
    nc=0;
    while (getchar() != EOF)
     ++nc;
    printf("%ld\n", nc);
}

Для его компиляции я заменяю main () на int main ().Но я предполагаю, что это не имеет отношения к вопросу.Программа компилируется и работает нормально.Но он просто не считает символы, как было написано.Я что-то пропустил?Могло ли что-то измениться в том, как современные компиляторы обрабатывают пример кода, подобного этому, с момента написания книги?Любая помощь, которую могут предложить хорошие люди на этой доске объявлений, будет принята с благодарностью.

Best, Dan

Ответы [ 4 ]

7 голосов
/ 05 сентября 2010

Программа выводит количество символов только после того, как прочитала «конец файла». С помощью интерактивного ввода вы можете сгенерировать «конец файла» с помощью ctrl + d (по крайней мере, в * NIX, понятия не имею об окнах). Зная это, программа корректно работает здесь.

7 голосов
/ 19 июня 2013

Хотя другие ответы технически верны, я чувствую, что этот пример (1.5.2) и следующий (1.5.3) сбивают с педагогического уровня. Просто гуглите «Количество персонажей 1.5.2», и вы найдете много других, которые попались на этом примере, как и ОП. Причина, по которой это так сбивает с толку, заключается в том, что в тексте нет объяснения о том, как сгенерировать символ EOF в интерактивном режиме, а предыдущие примеры выводили результаты сразу после ввода «return». Таким образом, любой новичок в C мог бы предположить, что программа в 1.5.3 должна сделать то же самое ...

Я хотел бы предложить следующий альтернативный код, который дает ожидаемый результат:

#include <stdio.h>
#define     EOL '\n'

main()
{
    long nc;
    int c;
    nc = 0;

    while ((c = getchar()) != EOF)
    {
        ++nc;
        if (c == EOL)
        {
            /* Print number of input characters (not including return character) */
            printf("%ld\n", nc-1); 
            nc = 0;
        }
    }
}

Единственный элемент C, который еще не объяснен в тексте, - это оператор if, который фактически будет объяснен в следующем разделе (1.5.3). Я надеюсь, что этот небольшой альтернативный пример поможет другим, кто увлекся оригинальным примером из книги K & R. Хорошим «Упражнением 1.7b» было бы изучить различия между двумя версиями и объяснить, что они выдают одинаковые результаты (прочитав о Ctrl D / Ctrl Z из других ответов).

5 голосов
/ 05 сентября 2010

Помимо возвращаемого значения main это выглядит нормально.

Делаете ли вы Ctrl D (Unix) или Ctrl Z (Windows) в конце вводаесли вы вводите значения с клавиатуры?

0 голосов
/ 23 июля 2017

Стоит также отметить, что Ctrl + z (который будет отображаться как ^ Z в консоли) не может быть просто введен в любом месте ввода консоли;Вы должны ввести его в качестве первого ввода последней строки строки / текста / символов.EG

Изображение начального ввода Ctrl + z

Как вы можете видеть в этом примере, я набирал произвольный текст и после окончания каждой строки нажимал клавишу ввода.СЕЙЧАС ЭТО ВАЖНО !!!Когда вы нажмете ввод в последней строке, он вызовет EOF (конец файла), и вы получите остальную часть кода, выполняющуюся так, как это было первоначально задумано.

Полностью выполненкод

Примечание:

  • Несмотря на то, что Ctrl + z отображается как ^ Z, программа не учитывает его как символ, сколько бы раз вы его ни нажимали.
  • Также символы после ctrl + z не учитываются.
  • Эта программа подсчитывает ввод

Источник: EOF в командной строке Windows незавершить поток ввода

...