Простая программа, добавляющая D к выводу

У меня есть очень простая программа, которая просто печатает количество новых строк как целое число, и я получаю «D» после каждого числа.

Пример ввода:
d [введите]
e [введите]
f [введите]
Ctrl-D [введите]

Пример вывода:
3D

Что я делаю не так?

Это дословно из второго издания языка программирования C, стр. 19:

#include <stdio.h>

main()  
{  
    int c, nl;  
    nl = 0;

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

person deadguy    schedule 20.09.2009    source источник
comment
Вы уверены, что D не просто происходит от Ctrl + D?   -  person Dale    schedule 20.09.2009
comment
На какой платформе вы работаете? MacOS X случайно?   -  person Jonathan Leffler    schedule 20.09.2009
comment
Спасибо за ответ, всем. Я использую OpenBSD 4.5.   -  person deadguy    schedule 23.09.2009
comment
См. также: C-программа печатает 0D вместо 0.   -  person Jonathan Leffler    schedule 30.11.2011


Ответы (3)


Я думаю, что D происходит от Ctrl D. Консоль выводит ^D как свою стандартную эхо-логику, прежде чем передать соответствующий char (или, скорее, отсутствие char, то есть статус EOF) в getchar(), однако, и по праву, не отправка cr/lf. Затем программа C отправляет свои 3, и вуаля...

Попробуйте программу, набрав более 9 CR перед выходом и проблема должна "уйти", т.е. не проявляться.

person mjv    schedule 20.09.2009
comment
Я не уверен, что никогда не видел таких вещей - person RageZ; 20.09.2009
comment
Вы, кажется, правы. Вы можете подтвердить это объяснение, добавив пару дополнительных символов новой строки в начало строки printf следующим образом: printf(\n\n%d\n, nl); Оболочка печатает ^D, а printf перезаписывает символ вставки своим выводом. - person Stephen Van Dahm; 20.09.2009
comment
@RageZ: я тоже раньше этого не делал, но тестирование на MacOS X (10.5.8) показывает именно такое поведение - к моему большому удивлению. - person Jonathan Leffler; 20.09.2009

Измените строку печати на это:

printf("\n%d\n", nl);

Затем вы увидите, что когда вы нажмете Ctrl-D, вы получите «^D» в строке. Только поскольку вы не нажали Ctrl-D, а затем Enter, то это не новая строка в исходной программе. Не все системы ответят вам ctrl-d, но, например, это происходит в OS-X. Таким образом, это приводит к тому, что вывод искажается, если вы печатаете однозначное число. Вам придется обойти это.

person indiv    schedule 20.09.2009
comment
Вы случайно не знаете, есть ли параметр stty, который управляет этим? - person Jonathan Leffler; 20.09.2009
comment
Отвечая на мой собственный комментарий/вопрос: stty echoctl включает его, а stty -echoctl отключает (то есть повторение управляющих символов, таких как ^D). - person Jonathan Leffler; 30.11.2011

Это отлично работает для меня с GCC, независимо от того, ввожу ли я ввод или вручную и заканчиваю ^D.

$ ./a.out
1
2
3
3
$ echo -ne "1\n2\n3\n" | ./a.out
3

Вероятно, как сказал @mjv, и консоль повторяет вам букву D -- вы работаете в Windows, верно? Думаю, это нормально для консоли Windows.

person Mark Rushakoff    schedule 20.09.2009
comment
Марк, в Windows это ctrl+z, который отправляет EOF. - person Nick Dandoulakis; 20.09.2009