EOF的概念
EOF是C语言中表示文件结束的标志符号,通常被定义为-1,它用于指示已到达文件的末尾或输入流的末尾。
EOF的使用
- 在输入操作中,EOF常常用于判断是否到达了文件末尾或输入流末尾,以便终止读取操作。例如,在使用scanf函数进行输入时,可以通过将scanf函数的返回值与EOF进行比较来判断是否读取到了文件结束符。
int result = scanf("%d", &n);
if (result == EOF) {
// 文件结束或输入流结束
} else {
// 成功读取输入
}
scanf的返回值:
scanf成功写入多少个数据,返回值就是多少,如果写入失败则返回EOF。
- 在文件操作中,当使用类似fgetc、fgets、fscanf等函数从文件中读取字符或字符串时,当读取到文件结束符EOF时,这些函数通常会返回EOF。
int ch = fgetc(file);
if (ch == EOF) {
// 文件结束
} else {
// 成功读取字符
}
需要注意的是,EOF并不是一个实际的字符或整数值,而是一个特殊的标志,用于指示文件结束或输入流结束的状态。
在不同的操作系统和编译器中,EOF的值可能会有所不同,但通常都是一个负整数(通常为-1)。因此,将函数的返回值与EOF进行比较,可以跨平台地判断文件结束。
但是在编译器输入操作中,输入无论是输入’-1‘还是输入EOF,其都是当作字符被成功地读入,并不能起到EOF的作用,也就是说while((c = getchar()) != EOF)
一直跳不出来,那输入通过什么能写入EOF标志呢?
如何表示输入结束
在 scanf
函数中,键盘输入 Ctrl+D (在Unix/Linux系统下) 或者 Ctrl+Z (在Windows系统下) 才会被读取到 EOF (End of File),表示输入结束。 EOF 是一个特殊的标记,用于指示输入流的结束。
另外,键盘输入Ctrl+C会强制停止程序的运行
使用EOF的具体情况
- 遇到多组输入的情况
我们可以看到在这道题目的输入描述中出现多组输入但是并没有告诉我们具体数量,在这个时候我们就需要用到EOF;
#include <stdio.h>
int main() {
int i;
while (scanf("%d", &i) != EOF) {
if (i % 2 == 0) {
printf("Even\n");
}
else {
printf("Odd\n");
}
}
return 0;
}
但是这段代码会遇到如下两个问题:
-
如果连续输入多个数字而不按下回车
-
如果输入数字以外的其他字符
分别会出现以下两种情况:
问题分析:
第一个情况涉及到输出缓冲区的概念:
在C语言中很多输出函数(如printf, putchar)便存在输出缓存. 在window系统下,使用printf()函数后,数据被写入到输出缓冲区,随后立即刷新缓冲区,所有我们在使用printf()函数时往往会很快就在控制台打印出来了。
第二个情况输入其他符号(例如~、.)会导致陷入死循环的原因是scanf函数无法成功解析这些非数字字符,并将其保留在输入缓冲区中。
当scanf函数无法成功解析输入时,它会将输入缓冲区中的内容保留,并返回0,表示读取失败。由于输入缓冲区中的内容与%d格式要求不匹配,scanf函数会一直返回0,导致循环无法终止,从而陷入死循环。
解决办法:
读取之后检查scanf
的返回值,以判断输入是否成功匹配并读取。
#include <stdio.h>
int main() {
int i;
int result;
while ((result = scanf("%d", &i)) != EOF) {
if (result == 1) {
if (i % 2 == 0) {
printf("Even\n");
} else {
printf("Odd\n");
}
} else {
printf("Invalid input\n");
break;
}
}
return 0;
}
在这个修改后的代码中,我们使用result变量来存储scanf函数的返回值。如果result等于1,表示成功读取了一个整数,并执行相应的逻辑。如果result不等于1,表示输入格式不符合预期,我们输出"Invalid input"并使用break语句跳出循环。
这样修改后,当输入其他非数字字符时,程序会输出"Invalid input",并跳出循环,而不会陷入死循环。
判断输入是否合法
如果输入错误需要重新输入而不是跳出循环的话,可以这样:
while ((result = scanf("%d", &i)) != EOF)
if (result != 1)
{
printf("输入不合法,请重新输入!\n");
while (getchar() != '\n');
continue;
}