为什么C程序打印0D而不是0?(EOF按Ctrl+D发送)[复制]

时间:2021-12-29 18:44:46

This question already has an answer here:

这个问题已经有了答案:

OSX 10.6.8, GCC 4.2 86_64

osx10.6.8, GCC 4.2 86_64。

#include <stdio.h>

/* count lines in input */
main()
{
    int c, nl;

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

Run

运行

./a.out

press ctrl+d to send EOF

按ctrl+d发送EOF。

0D

It should be just 0. Why does it append D? What does it mean?

应该是0。为什么它附加了D?这是什么意思?

2 个解决方案

#1


16  

I've seen this one - it confused me, too.

我也见过这个——它也把我弄糊涂了。

The terminal is echoing ^D and then the 0 is output from the program, overwriting the caret.

终端是呼应^ D然后0输出程序,覆盖插入符号。

You can demonstrate this by changing the print format in your program to "\n%d\n".

您可以通过将程序中的打印格式改为“\n%d\n”来演示这一点。


When asked 'Why?', I went exploring. The answer is in the tty settings. For my terminal, the output from stty -a is:

当被问及“为什么?的,我去探索。答案就在tty的设置里。对于我的终端,stty -a的输出是:

speed 9600 baud; 65 rows; 120 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^X; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

Notice the echoctl at the end of the second line - it is for 'echo control characters'.

请注意第二行末尾的echoctl——它是用于“echo控制字符”的。

$ stty -echoctl
$ cat > /dev/null
asdsadasd
$ stty echoctl
$ cat > /dev/null
asasada^D
$

You can't see it, but for each cat command, I typed a Control-D at the end of the line of asd characters, and a second one after hitting return. The prompt erased the second echoed ^D in the second example.

你看不到它,但是对于每一个cat命令,我在asd字符行末尾键入一个Control-D,在返回后再键入第二个。提示删除第二个^ D在第二个例子中回荡。

So, if you don't like the control characters being echoed, turn the echoing off:

所以,如果你不喜欢这些控制角色的回声,那就把回声关掉:

stty -echoctl

The shell can also get in the way; I experimented with Control-R and my shell (bash) decided to go into

外壳也会碍事;我尝试了Control-R和我的外壳(bash)决定进入。

(reverse-i-search)`': aasadasdadadasdadadadadadsad

I'd typed the unoriginal sequence of 'asd' characters and then typed Control-R, and this is where I ended up in the shell. I interrupted; I'm not sure what a reverse-i-search is, but I suspect it is Emacs-ish; it was not what I expected.

我输入了“asd”字符的非原始序列,然后键入Control-R,这就是我最终在shell中结束的地方。我打断;我不知道什么是反向搜索,但我怀疑它是Emacs-ish;这不是我所期望的。

#2


1  

Running Xcode on Mac OSX got this output:

在Mac OSX上运行Xcode得到了这个输出:

First Line
Second Line
Now I'm going to press control D after return.
3

第一行第二行,现在我要在返回后按控制D。3

#1


16  

I've seen this one - it confused me, too.

我也见过这个——它也把我弄糊涂了。

The terminal is echoing ^D and then the 0 is output from the program, overwriting the caret.

终端是呼应^ D然后0输出程序,覆盖插入符号。

You can demonstrate this by changing the print format in your program to "\n%d\n".

您可以通过将程序中的打印格式改为“\n%d\n”来演示这一点。


When asked 'Why?', I went exploring. The answer is in the tty settings. For my terminal, the output from stty -a is:

当被问及“为什么?的,我去探索。答案就在tty的设置里。对于我的终端,stty -a的输出是:

speed 9600 baud; 65 rows; 120 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^X; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

Notice the echoctl at the end of the second line - it is for 'echo control characters'.

请注意第二行末尾的echoctl——它是用于“echo控制字符”的。

$ stty -echoctl
$ cat > /dev/null
asdsadasd
$ stty echoctl
$ cat > /dev/null
asasada^D
$

You can't see it, but for each cat command, I typed a Control-D at the end of the line of asd characters, and a second one after hitting return. The prompt erased the second echoed ^D in the second example.

你看不到它,但是对于每一个cat命令,我在asd字符行末尾键入一个Control-D,在返回后再键入第二个。提示删除第二个^ D在第二个例子中回荡。

So, if you don't like the control characters being echoed, turn the echoing off:

所以,如果你不喜欢这些控制角色的回声,那就把回声关掉:

stty -echoctl

The shell can also get in the way; I experimented with Control-R and my shell (bash) decided to go into

外壳也会碍事;我尝试了Control-R和我的外壳(bash)决定进入。

(reverse-i-search)`': aasadasdadadasdadadadadadsad

I'd typed the unoriginal sequence of 'asd' characters and then typed Control-R, and this is where I ended up in the shell. I interrupted; I'm not sure what a reverse-i-search is, but I suspect it is Emacs-ish; it was not what I expected.

我输入了“asd”字符的非原始序列,然后键入Control-R,这就是我最终在shell中结束的地方。我打断;我不知道什么是反向搜索,但我怀疑它是Emacs-ish;这不是我所期望的。

#2


1  

Running Xcode on Mac OSX got this output:

在Mac OSX上运行Xcode得到了这个输出:

First Line
Second Line
Now I'm going to press control D after return.
3

第一行第二行,现在我要在返回后按控制D。3