Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
EOF未按预期工作(C)_C_While Loop_Eof - Fatal编程技术网

EOF未按预期工作(C)

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) {

我正在尝试使用EOF函数,但它没有像我预期的那样工作。在调试器模式下,它不会检测第二个“scanf”函数,只会继续执行。它时不时地漏掉“scanf”函数。代码发布在下面

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
    }
}