混淆缓冲区和 EOF 和 getchar
confusing with buffer and EOF and getchar
我用 getchar()
和 putchar()
以及 '\n'
和 EOF(在 Visual Studio 中)测试了很多情况,以更好地理解缓冲和 getchar
的工作原理.
如果我的代码
int c;
printf("Enter character\n");
/* 1 - number for explaining steps */
c = getchar();
putchar(c);
/* 2 */
c = getchar();
putchar(c);
printf("hi");
在此代码中,如果我输入字符 a
并按 Enter,它将显示
a
hi
这意味着当我按下回车时,'\n'
也会被保存在缓冲区中,然后缓冲区中的第一项(a
)会转到第一个c=getchar()
和 a
被打印出来;然后缓冲区中的第二个项目 (\n
) 转到第二个
c=getchar()
并打印新行。
我得出结论,'\n'
保存在缓冲区中,这不是命令在按 enter 时能够转到新行的结果,因为我为此测试了另一个代码:
while ((c = getchar()) != '\n')
putchar(c);
printf("hi");
在这段代码中,当我输入 a
并按回车键时,它会打印 ahi
并且不会打印新行,这意味着当 a
传递给 getchar()
时, putchar()
然后当 getchar()
得到 '\n'
时打印它,循环终止并且循环内的 putchar()
不打印新行所以命令不是新行。
现在我想测试另一个代码:
int c;
while ((c = getchar()) != EOF)
putchar(c);
printf("hi");
return 0;
在这一个中,如果我传递它 abc
和 EOF 信号(在我的系统中 ^Z (Ctrl+Z))它将显示 abc->
.如果我们像以前的代码一样看它:
abc-1(or every thing else shows eof)'\n'
应该保存在缓冲区中,首先 a
转到第一个 getchar(第一次循环工作) b
传递给第二个 getchar 然后 c
传递给第三个— 然后 -1
应该传递给 c=getchar()
它违反了条件,循环应该终止。
但是,它会打印 ->
并继续循环,并且不会打印新行(缓冲区中的最后一项)。
相反,当我 ctr +z
当 c=getchar()
从缓冲区读取 EOF 符号时,循环终止并打印新行,那么为什么它打印新行?
它读取 EOF,不应读取缓冲区中的任何其他内容
在这种情况下。
第一个例子中输入先读a
然后换行的概述基本上是正确的。就 getchar()
而言,换行符是一个完全正常的字符;的确,没有异常的字符。 getchar()
可以 return 任何适合 char
的 8 位值,加上一个附加值,称为 EOF。这就是为什么它的 return 值必须存储在 int
中,正如您所做的那样。
当底层 read()
系统调用 return 0 个字节可供读取时,标准 I/O 函数 return EOF — 或者出现错误时。
当您在 Windows 上键入 abc
Control-Z 时(您将键入 Control-D而不是在 Unix 上),然后:
- 终端驱动程序使当前在其缓冲区 (
abc
) 中的字符可用于 read()
系统调用。
read()
系统调用使用这些字符填充标准 I/O 缓冲区。
- 连续的
getchar()
调用 return a
、b
和 c
。
- 下一个
getchar()
等待更多输入。
这不是 EOF;它只是将行中的字符刷新到程序中。要获得 EOF 的效果,您必须在 abc
之后连续输入两次 Control-Z。第一个会刷新 abc
;第二个将生成 0 字节的 read()
,表示 EOF。
终端驱动程序还可以在按下换行符 (Enter) 时提供输入。如果您在键入 Enter 后立即键入 Control-Z,待输入字符的所有零都将从终端发送到程序,因此 read()
returns 0,所以标准 I/O 包报告 EOF。
请注意,在您按下回车键或 EOF 指示之前,您可以使用退格键和其他编辑选项编辑行中的数据,包括删除所有数据。一旦您按下回车键或 EOF 指示,您将无法再编辑 read()
.
可用的数据
类似的行为发生在 Unix 上;您键入 EOF 指示两次以终止输入中线; once 在一行的开头终止输入。
Stack Overflow 上有很多相关问题,包括这些:
- Canonical vs non-canonical terminal input
while ((c = getc(file)) != EOF)
loop won't stop executing
- Control-D didn't stop the
while (getchar() != EOF)
loop
- How to stimulate EOF without preceding newline in C?
read()
from stdin doesn't ignore newline
我用 getchar()
和 putchar()
以及 '\n'
和 EOF(在 Visual Studio 中)测试了很多情况,以更好地理解缓冲和 getchar
的工作原理.
如果我的代码
int c;
printf("Enter character\n");
/* 1 - number for explaining steps */
c = getchar();
putchar(c);
/* 2 */
c = getchar();
putchar(c);
printf("hi");
在此代码中,如果我输入字符 a
并按 Enter,它将显示
a
hi
这意味着当我按下回车时,'\n'
也会被保存在缓冲区中,然后缓冲区中的第一项(a
)会转到第一个c=getchar()
和 a
被打印出来;然后缓冲区中的第二个项目 (\n
) 转到第二个
c=getchar()
并打印新行。
我得出结论,'\n'
保存在缓冲区中,这不是命令在按 enter 时能够转到新行的结果,因为我为此测试了另一个代码:
while ((c = getchar()) != '\n')
putchar(c);
printf("hi");
在这段代码中,当我输入 a
并按回车键时,它会打印 ahi
并且不会打印新行,这意味着当 a
传递给 getchar()
时, putchar()
然后当 getchar()
得到 '\n'
时打印它,循环终止并且循环内的 putchar()
不打印新行所以命令不是新行。
现在我想测试另一个代码:
int c;
while ((c = getchar()) != EOF)
putchar(c);
printf("hi");
return 0;
在这一个中,如果我传递它 abc
和 EOF 信号(在我的系统中 ^Z (Ctrl+Z))它将显示 abc->
.如果我们像以前的代码一样看它:
abc-1(or every thing else shows eof)'\n'
应该保存在缓冲区中,首先 a
转到第一个 getchar(第一次循环工作) b
传递给第二个 getchar 然后 c
传递给第三个— 然后 -1
应该传递给 c=getchar()
它违反了条件,循环应该终止。
但是,它会打印 ->
并继续循环,并且不会打印新行(缓冲区中的最后一项)。
相反,当我 ctr +z
当 c=getchar()
从缓冲区读取 EOF 符号时,循环终止并打印新行,那么为什么它打印新行?
它读取 EOF,不应读取缓冲区中的任何其他内容
在这种情况下。
第一个例子中输入先读a
然后换行的概述基本上是正确的。就 getchar()
而言,换行符是一个完全正常的字符;的确,没有异常的字符。 getchar()
可以 return 任何适合 char
的 8 位值,加上一个附加值,称为 EOF。这就是为什么它的 return 值必须存储在 int
中,正如您所做的那样。
当底层 read()
系统调用 return 0 个字节可供读取时,标准 I/O 函数 return EOF — 或者出现错误时。
当您在 Windows 上键入 abc
Control-Z 时(您将键入 Control-D而不是在 Unix 上),然后:
- 终端驱动程序使当前在其缓冲区 (
abc
) 中的字符可用于read()
系统调用。 read()
系统调用使用这些字符填充标准 I/O 缓冲区。- 连续的
getchar()
调用 returna
、b
和c
。 - 下一个
getchar()
等待更多输入。
这不是 EOF;它只是将行中的字符刷新到程序中。要获得 EOF 的效果,您必须在 abc
之后连续输入两次 Control-Z。第一个会刷新 abc
;第二个将生成 0 字节的 read()
,表示 EOF。
终端驱动程序还可以在按下换行符 (Enter) 时提供输入。如果您在键入 Enter 后立即键入 Control-Z,待输入字符的所有零都将从终端发送到程序,因此 read()
returns 0,所以标准 I/O 包报告 EOF。
请注意,在您按下回车键或 EOF 指示之前,您可以使用退格键和其他编辑选项编辑行中的数据,包括删除所有数据。一旦您按下回车键或 EOF 指示,您将无法再编辑 read()
.
类似的行为发生在 Unix 上;您键入 EOF 指示两次以终止输入中线; once 在一行的开头终止输入。
Stack Overflow 上有很多相关问题,包括这些:
- Canonical vs non-canonical terminal input
while ((c = getc(file)) != EOF)
loop won't stop executing- Control-D didn't stop the
while (getchar() != EOF)
loop - How to stimulate EOF without preceding newline in C?
read()
from stdin doesn't ignore newline