【发布时间】:2014-02-17 07:33:24
【问题描述】:
我被 K&R 中的 1.5.2 问题难住了。我google了一段时间,发现输入字符后我必须提供EOF输入。
long nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
return 0;
我尝试将 command-D 和 control-D 作为 EOF 输入,但没有任何效果。知道如何为 Mac OS X 提供 EOF?
【问题讨论】:
我被 K&R 中的 1.5.2 问题难住了。我google了一段时间,发现输入字符后我必须提供EOF输入。
long nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
return 0;
我尝试将 command-D 和 control-D 作为 EOF 输入,但没有任何效果。知道如何为 Mac OS X 提供 EOF?
【问题讨论】:
默认情况下,当在行首按下 Control-D 时,macOS(以前称为 OS X 和 Mac OS X)软件会识别 EOF。 (我相信其他版本的 Unix 也有类似的行为。)
具体来说,实际操作是,当 Control-D被按下时,终端输入缓冲区中的所有字节都被发送到使用终端的正在运行的进程。在一行的开头,缓冲区中没有字节,因此进程被告知有零字节可用,这充当EOF 指示符。
此过程兼作在行尾之前向进程传递输入的方法:用户可以键入一些字符并按 Control-D,这些字符将被发送到进程立即,无需通常等待输入/返回被按下。执行“立即发送所有缓冲的字节”操作后,缓冲区中没有任何字节。所以,当 Control-D 被第二次按下时,它与一行的开头相同(不发送字节,进程被赋予零字节),它的作用就像一个@ 987654323@.
您可以通过在终端中使用命令“man 4 tty”来了解有关终端行为的更多信息。默认线路规程是 termios。您可以使用命令man termios 了解有关 termios 行规则的更多信息。
【讨论】:
getchar() 的工作原理吗?我认为 get char 一次只能容纳一个字符。当我在终端中输入hdjshj 之类的字符串并输入文件末尾时,getchar 会一次存储整个字符串吗?还是一输入终端就存储字符,遇到EOF就停止存储?
getchar 看到字符之前/下方。 getchar 是程序中软件的一部分(从软件库链接),用于管理文件和缓冲区。该软件调用类似read 的系统调用来获取字节。另外,还有一些软件可以操作您看到的“终端”窗口,以及从键盘读取字符的软件。终端软件从键盘接收字符(通过额外的系统软件层)并处理它们。...
read 系统调用将它们返回给调用者。调用者是管理程序中文件和缓冲区的软件的一部分。...
getchar 时,它会从该缓冲区中拉出一个字符(如果那里有一个字符)。 (如果没有,它会请求填充缓冲区,这会导致另一个read 调用被执行。)getchar 只有一个保证位置,ungetchar 可以放回一个字符,但其中可能有多个字符内部缓冲区。 (有多种方法可以关闭某些缓冲,以便您可以更直接地从终端读取字符,但大多数程序不需要这样做。)
如果您想查看终端中设置的 EOF,您可以输入
stty all
在我的 Mac 上,这给出了输出 -
speed 9600 baud; 24 rows; 80 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
discard dsusp eof eol eol2 erase intr kill lnext
^O ^Y ^D <undef> <undef> ^? ^C ^U ^V
min quit reprint start status stop susp time werase
1 ^\ ^R ^Q ^T ^S ^Z 0 ^W
从下往上可以看到四行,eof中的三个单元格是^D。
有一个更完整的描述 here 这是我找到信息的地方。
【讨论】:
我刚刚想通了。您必须按 Ctrl+D+D。按住控件并按 D 两次。我不得不说一个奇怪的键序列。
【讨论】: