提问人:Hiểu Nam 提问时间:7/26/2023 最后编辑:ptsHiểu Nam 更新时间:7/26/2023 访问量:73
在 C 语言中 getchar() 中使用 EOF (Ctrl + D)
The use of EOF (Ctrl + D) in getchar() in C
问:
我正在阅读K&R中的第1.9节,我不明白在下面实现的代码中使用EOF
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int mymygetline(char line[], int maxline);
void copy(char to[], char from[]);
/* print the longest input line */
int main()
{
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = mymygetline(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* mymygetline: read a line into s, return length */
int mymygetline(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
我试过什么:
- 初始程序运行良好,输入标记带有“\n”的差异行很容易理解
- 当我第一次尝试以内联方式输入 EOF 时,它只是结束最近的输入流并将 getchar() 设置为输入流的等待模式。
问题:
- 当我两次内联输入 EOF 时,第一个 EOF 是否只是像“\n”或其他机制一样,或者我只是在这里遗漏了一些东西。
答:
1赞
pts
7/26/2023
#1
以下是按键传播到代码 (mymygetline()) 函数的方式:
- 用户按下该键。
- 键盘接收按键,并向类 Unix 操作系统发送某种包含键码的事件。
- 操作系统确定应将事件路由到终端(这包括 GUI 上的终端仿真器窗口)。操作系统将事件转换为字节序列,并将其发送到终端。
- 终端可能会进行更多的转换和缓冲。默认情况下,它会缓冲(即不让通过)字节,直到收到换行符或特殊内容(例如对应于 Ctrl-D 的字符)。
- 程序中的 libc 代码(由 getchar(3) 调用)从终端读取一系列字节。当终端处于缓冲状态时, libc 代码会阻塞 read(2) 系统调用。一旦终端刷新,read(2) 就会同时接收到许多字节,通常是整行后跟换行符,或者是 EOF 指示符(read(2) 返回 0)。
- 您的代码 (mymygetline()) 从 getchar(3) 接收 read(2) 读取的字节,一次一个字节。一旦没有更多的字节可用,libc 代码就会再次调用 read(2),它会阻塞,直到有更多的字节出现。
如果用户按下 Ctrl-D,read(2) 返回到目前为止缓冲的字节数(如果有的话),后续的 read(2)(由第二个 Ctrl-D 触发)返回 0,这会导致 getchar(3) 返回 EOF。
评论
EOF
(c = getchar ()) != EOF && c != '\n'
EOF
stdin
./myprog
"dog[ctrl + d]"
EOF
mymygetline()
> 0
"dog[Enter][ctrl + d]"
[Enter]
'\n'
mymygetline()