mac-osx终端中的信号EOF

mac-osx终端中的信号EOF,c,kernighan-and-ritchie,C,Kernighan And Ritchie,我被K&R中的1.5.2问题难住了。我在谷歌上搜索了一段时间,发现我必须在输入字符后提供EOF输入 long nc = 0; while (getchar() != EOF) ++nc; printf("%ld\n", nc); return 0; 我尝试将commnad-D和control-D作为EOF输入,但没有任何效果。你知道如何为mac osx提供EOF吗?我刚想出来。您必须按Ctrl+D+D。按住控件并按D两次。我得说这是一个多么奇怪的键序列 默认情况下,当在行首按Ctr

我被K&R中的1.5.2问题难住了。我在谷歌上搜索了一段时间,发现我必须在输入字符后提供EOF输入

long nc = 0;

while (getchar() != EOF)
    ++nc;
printf("%ld\n", nc);

return 0;

我尝试将commnad-D和control-D作为EOF输入,但没有任何效果。你知道如何为mac osx提供EOF吗?

我刚想出来。您必须按Ctrl+D+D。按住控件并按D两次。我得说这是一个多么奇怪的键序列

默认情况下,当在行首按Ctrl-D时,macOS(以前的OS X和Mac OS X)软件会识别
EOF

具体地说,实际操作是,当按下Ctrl-D时,终端输入缓冲区中的所有字节都使用终端发送到正在运行的进程。在一行的开头,缓冲区中没有字节,因此进程被告知有零字节可用,这起到了
EOF
指示器的作用

此过程同时作为一种在行尾之前向流程发送输入的方法:用户可以键入一些字符并按Ctrl-D,字符将立即发送到流程,而无需通常等待按enter/return。执行此“立即发送所有缓冲字节”操作后,缓冲区中没有剩余字节。因此,当第二次按下Ctrl-D时,它与一行的开头相同(不发送任何字节,进程被赋予零字节),并且它的作用类似于
EOF


通过在终端中使用命令“man4tty”,您可以了解有关终端行为的更多信息。默认的行规程是termios。您可以通过使用命令
man termios

了解有关termios线路规程的更多信息。如果您想查看终端中设置的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     
速度9600波特;24排;80列;
lflags:icanon isig iexten echo-echok echoke-echonl echoctl
-echoprt-altwerase-noflsh-tostop-flusho pendin-Nokerinfo
-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
丢弃dsusp eof eol eol2擦除intr kill lnext
^O^Y^D^^C^U^V
最小退出重新打印开始状态停止暂停时间为
1^^R^Q^T^S^Z 0^W
从底部可以看到四行,eof中的三个单元格是^D


这里有一个更完整的描述,这是我找到信息的地方。

你能帮我理解
getchar()
的工作原理吗?我认为get char一次只能保存一个字符。当我在终端中输入一个像
hdjshj
这样的字符串,并输入文件的结尾时,
getchar
会立即存储整个字符吗?还是在输入终端后立即存储字符,并在遇到EOF时停止存储?@Morpheus:我在回答中讨论的字符处理在
getchar
看到字符之前/下方
getchar
是程序中管理文件和缓冲区的软件的一部分(从软件库链接)。该软件调用类似于
read
的系统调用来获取字节。另外,还有操作您看到的“终端”窗口的软件和从键盘读取字符的软件。终端软件从键盘接收字符(通过附加的系统软件层)并对其进行处理。…@Morpheus:…通常,终端软件会记住缓冲区中的普通字符,并以各种方式处理特殊字符。例如,当它看到一个control-C时,它可能会向正在运行的进程发送一个信号来中断它。当它看到return/enter时,它将缓冲字符和return/enter发送到正在运行的进程。当字符以这种方式发送到正在运行的进程时,
read
系统调用将它们返回给调用者。调用者是管理程序中文件和缓冲区的软件的一部分…@Morpheus:…该软件有自己的缓冲区。当您调用
getchar
时,如果缓冲区中有一个字符,它会从缓冲区中取出一个字符。(如果没有,它将请求填充缓冲区,这将导致执行另一个
读取
调用。)
getchar
只有一个保证点,其中
ungetchar
可以放回一个字符,但内部缓冲区中可能有多个字符。(有多种方法可以关闭某些缓冲,以便您可以更直接地从终端读取字符,但大多数程序不需要这样做。)这并不能回答问题:“知道如何为mac osx提供EOF吗?”您应该通过两次Ctrl-D来获得相同的行为(即连续按住Ctrl键不相关)