EOF未按预期工作(C)
我正在尝试使用EOF函数,但它没有像我预期的那样工作。在调试器模式下,它不会检测第二个“scanf”函数,只会继续执行。它时不时地漏掉“scanf”函数。代码发布在下面EOF未按预期工作(C),c,while-loop,eof,C,While Loop,Eof,我正在尝试使用EOF函数,但它没有像我预期的那样工作。在调试器模式下,它不会检测第二个“scanf”函数,只会继续执行。它时不时地漏掉“scanf”函数。代码发布在下面 int main() { char tempString; int i = 0; printf("Enter your letter\n"); scanf_s("%c", &tempString); while (tempString != EOF) {
int main() {
char tempString;
int i = 0;
printf("Enter your letter\n");
scanf_s("%c", &tempString);
while (tempString != EOF) {
printf("You entered:%c\n", tempString);
scanf_s("%c", &tempString);
}
}
我也尝试过使用getchar()函数,但出现了同样的情况,代码发布如下:
int main() {
char tempString;
int i = 0;
printf("Enter your letter\n");
while ((tempString = getchar()) != EOF) {
printf("You entered:%c\n", tempString);
}
}
感谢阅读编辑:
首先,您省略了%c
和%s
格式的scanf_s
所需的长度参数
其次,%c
格式从输入缓冲区中获取下一个字符。在第二个(以及随后的)条目中,在第一个输入的输入缓冲区中留下了一个换行符。在%c
格式说明符之前添加空格
,可清除前导空格
#include <stdio.h>
int main(void)
{
char ch_scanf; // char type
int ch_getchar; // int type
printf("Using scanf_s\n");
if (scanf_s(" %c", &ch_scanf, 1) == 1) { // consumes any leading whitespace
printf("scanf_s value: %d\n", ch_scanf);
}
if (scanf_s(" %c", &ch_scanf, 1) == 1) { // consumes any leading whitespace
printf("scanf_s value: %d\n", ch_scanf);
}
printf("\nUsing getchar\n");
while ((ch_getchar = getchar()) != EOF) {
printf("getchar value: %d\n", ch_getchar);
}
return 0;
}
其他格式,如%s
和%d
忽略前导空格,但不忽略%c
第三,使用scanf
使用EOF
不是一个好办法,您应该使用scanf
的返回值来控制循环,该值告诉您成功读取的项目数
此程序使用scanf\u s
启动。第二个条目忽略第一个条目后的换行符
然后使用getchar
。在这个测试中,函数返回值是int
,所以这是我的数据类型。这样,EOF
(-1)就不会与任何必需的字符数据冲突。请注意,getchar
首先读取上一个scanf\u
后面的换行符
(它只忽略前导空格)
#include <stdio.h>
int main(void)
{
char ch_scanf; // char type
int ch_getchar; // int type
printf("Using scanf_s\n");
if (scanf_s(" %c", &ch_scanf, 1) == 1) { // consumes any leading whitespace
printf("scanf_s value: %d\n", ch_scanf);
}
if (scanf_s(" %c", &ch_scanf, 1) == 1) { // consumes any leading whitespace
printf("scanf_s value: %d\n", ch_scanf);
}
printf("\nUsing getchar\n");
while ((ch_getchar = getchar()) != EOF) {
printf("getchar value: %d\n", ch_getchar);
}
return 0;
}
最后,如果您想使用标准库函数scanf
,而不需要MSVC勾选,您可以这样做
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
\define\u CRT\u SECURE\u NO\u警告
#包括
试试这个
#include <stdio.h>
int main(void) {
char tempString;
printf("Enter your letter\n");
while (scanf_s("%c%*c", &tempString, 1) != EOF) {//%*c for consume newline, 1 is buffer size
printf("You entered:%c\n", tempString);
}
return 0;
}
C语言中scanf()函数的行为
从键盘缓冲区读取输入,直到遇到EOF(即,直到
按回车键)
通常,不建议在c中使用“%c”来读取输入字符,因为
该值被收集在键盘缓冲区中,直到我们按下enter键,并且我们不能限制用户输入单个字符
因此,获取字符的最佳方法是使用getchar()函数
在您提供的程序中,您可以使用任何其他字符检查结束,而不是EOF
,因为它在scanf()
实现中用于标记输入结束
您可以使用其他键,如esc
,检查是否结束
#include <stdio.h>
#include <stdlib.h>
#define esc 27
int main()
{
char ch;
while((ch = getchar()) != esc) {
//print the entered character here
}
}
#包括
#包括
#定义esc 27
int main()
{
char ch;
而((ch=getchar())!=esc){
//在此处打印输入的字符
}
}
要深入了解scanf()
实现,请查看此tempString
应该是int
scanf\u s
在EOF或失败时返回EOF,它不会用EOF填充输出参数,因此检查它是毫无价值的。scanf\u
有一个返回代码,请使用它(提示:在您的while状态下,消除对scanf\u s
的尾部调用是值得尝试的)。对于第二种情况,int
确实是tempString
的正确decl。我希望您意识到,在这两种情况下,通过点击kb输入的后续回车/换行符不会消失在空气中。它将在下一个循环迭代的输入流中等待。EOF
不是f的实际结束您读取的文件字符,它只是一些函数返回的一个值,表示它们遇到了文件/流的结尾。在文件结尾,通常没有用于scanf()
或scanf_s()的EOF字符
读取时,它们只会指示返回值失败。虽然存在文件结尾字符(仅在某些情况下,并不总是使用),但它与您使用的EOF
常量/宏不同。除了毫无意义之外,scanf_()需要一个额外的参数,但您没有提供。(您的编译器应该对此发出警告)。这可能会使程序更加危险。(在本例中不是这样,“%c”相对无害)缓冲区大小要求也包括%c
。对于包含在[]中的c、c、s、s或字符串控制集类型的所有输入参数,都要指定缓冲区大小。缓冲区大小(以字符为单位)将作为附加参数在指向缓冲区或变量的指针后立即传递。首先,感谢您给出答案,但我没有看到您在一段时间内使用EOF函数loop@BiaKhan如果您修改了答案,以比较scanf_s
和getchar
的使用情况……请注意>EOF
不是一个函数。它是一个给出整数值的宏。之所以使用EOF
不是控制scanf\u
的最佳方法,是因为当它不是文件结尾时,它不会捕获无效输入。例如输入错误的数据类型,scanf\u
返回0
已转换的项。在函数中main
:未定义对getch
的引用。我想,它应该是getchar()
?如果是这样,那么它也应该是int ch;
。是的!根据C99,它是getchar()。编辑代码。@pzaenger“直到遇到EOF”不是“直到我们按下回车键”,这可能是行的结尾,但不是文件的结尾(和scanf()
无论如何都将读取超过行尾)。您似乎将行缓冲与scanf()
…关联,但行缓冲是在输入到达scanf()
或其他输入函数之前发生的一件单独的事情,并且不会更改只能在以下情况下读取的输入。此外,getch()
是非标准的,实际上并不等同于getchar()
#include <stdio.h>
#include <stdlib.h>
#define esc 27
int main()
{
char ch;
while((ch = getchar()) != esc) {
//print the entered character here
}
}