关于EOF的一个小问题,求解。

时间:2021-10-26 19:30:33
#include <stdio.h> 

int  main() 
{
int num;
char c,a;
while ((c=getchar())!=EOF)
{
putchar(c);
}
return 0;

输入:a^Z\n后为什么不能终止循环?而是终止该行,然后打印了一个a,再单独输入一个^Z才能结束循环?
个人觉得是不是第一个^Z从流获取了之后作为该流结束,不赋值给c,所以也就没下文了,但是为什么再次输入一个^Z就赋值给c了呢?求解。谢谢。

23 个解决方案

#1


顶起来。。。沉了都。。。求解啊。。。

#2



#include <stdio.h>  

int main()  
{
int num;
char c,a;
while ((c=getchar())!=EOF)
{
putchar(c);
}
return 0;
}  

//输入 asdfdf(一串字符)回车然后再输入ctrl+z然后回车就可以退出了

#3


你没看明白我的问题。。我问的是为什么要单独输入^Z才能终止,直接在字符串后面输入^Z不可以。。。不是怎么退出这个程序哈。。求解。。谢谢。
引用 2 楼 hnuqinhuan 的回复:
C/C++ code

#include <stdio.h>  

int main()  
{
    int num;
    char c,a;
    while ((c=getchar())!=EOF)
    {
        putchar(c);
    }
    return 0;
}  

//输入 asdfdf(一串字符)回车然后再输入ctr……

#4


因为“规定”,操作系统的规定,和c、c++没关系。

#5


因为程序需要你按一个“确定”键,这时是Ctrl+Z就当做是确定键输入了
这时需要再一次按Ctrl+Z才能退出,不然还是可以继续输入字符的
个人觉得是这样的

#6


引用 4 楼 taodm 的回复:
因为“规定”,操作系统的规定,和c、c++没关系。


++

#7


该回复于2011-11-14 10:52:07被版主删除

#8


该回复于2011-11-14 10:52:06被版主删除

#9


那是控制台的截断操作吧
跟C++没有关系的

#10


二楼的是正解
我开始学习的时候也有过这样的困惑;
那个EOF是指函数的返回值,而不是 c 的值,

你可以测试下面的程序:

#include<stdio.h>
#include<stdlib.h>

int main()
{
  int a,b;
  b=scanf("%d",&a);
  printf("%d %d",a,b);
   
  system("pause");
  return 0;   
    

/*输入数字结果是1 字母是0 EOF(CTRL+z) 是-1 */

#11


我把getchar返回值给c了。。有区别吗。。我是想知道为什么单独输入^Z\n和在abc^Z\n这样输入,对^Z的处理有什么不同。和EOF没关系哈。。为什么前者能终止循环,后者不行。感觉和流的处理有关系,后者应该是把^Z当做流的终止符了,没有赋值给C,但是为什么前者没有当做终止符而是直接给C了呢?楼上各位大神求教啊。。
引用 10 楼 huangd29 的回复:
二楼的是正解
我开始学习的时候也有过这样的困惑;
那个EOF是指函数的返回值,而不是 c 的值,

你可以测试下面的程序:

#include<stdio.h>
#include<stdlib.h>

int main()
{
  int a,b;
  b=scanf("%d",&amp;a);
  printf("%d %d",a,b);
   
  system(……

#12


EOF 是scanf和getchar的返回值哈。你那样写肯定输一次不行,得输入两次

#13


引用 4 楼 taodm 的回复:
因为“规定”,操作系统的规定,和c、c++没关系。


LZ,我以前发过跟你差不多的帖子,我发的是50分,下面这个回答我给了他40分:

windows下输入完后完回车后按ctrl+z 再按回车。
linux/unix下输入完后按回车后按ctrl+d再按回车。
或者在命令行上通过管道把文件的内容进行计数。
program < test.txt 

#14


按下Ctr + z 还不能够退出循环吗?

#15


其实对这样的问题,我觉得没有必要去纠集。

EOF 就是 文件结尾。
实际的程序肯定是 直接文件操作的,不太可能,控制台手工输入的

真实的环境是文件输入,可定能 终止循环

#17


^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环

#18


不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
 if (条件1) break;
 //...
 if (条件2) continue;
 //...
 if (条件3) return;
 //...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
whlie (!feof(f)) {
 a=fgetc(f);
 //...
 b=fgetc(f);//可能此时已经feof了!
 //...
}
而这样写就没有问题:
whlie (1) {
 a=fgetc(f);
 if (feof(f)) break;
 //...
 b=fgetc(f);
 if (feof(f)) break;
 //...
}
类似的例子还可以举很多。

#19


这个能不能用 ctrl + c 结束呢?

#20


引用 17 楼 selooloo 的回复:
^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环


我觉得这个兄弟有道理,^z只是一个标志,代表读取结束,比如输入ab^zcd,getchar读取缓冲区时候只读取到了ab和26,这个26可能是ctrl+z的码值,遇到^z就不读了,
如果你直接输入^z的话,就是告诉getchar缓冲区里第一个就是终止符,无数据。自然返回EOF了

#21


引用 20 楼 yuqangy 的回复:
引用 17 楼 selooloo 的回复:
^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环


我觉得这个兄弟有道理,^z只是一个标志,代……


++

#22


学习了! 确实很精彩! 
引用 18 楼 zhao4zhong1 的回复:
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
 if (条件1) break;
 //...
 if (条件2) continue;
 //...
 if (条件3) return;
 //...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语……

#23


我近天也是这个问题, 终于解决了, 哈哈~~~谢谢大家哈! 学习了!
引用 17 楼 selooloo 的回复:
^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环

#1


顶起来。。。沉了都。。。求解啊。。。

#2



#include <stdio.h>  

int main()  
{
int num;
char c,a;
while ((c=getchar())!=EOF)
{
putchar(c);
}
return 0;
}  

//输入 asdfdf(一串字符)回车然后再输入ctrl+z然后回车就可以退出了

#3


你没看明白我的问题。。我问的是为什么要单独输入^Z才能终止,直接在字符串后面输入^Z不可以。。。不是怎么退出这个程序哈。。求解。。谢谢。
引用 2 楼 hnuqinhuan 的回复:
C/C++ code

#include <stdio.h>  

int main()  
{
    int num;
    char c,a;
    while ((c=getchar())!=EOF)
    {
        putchar(c);
    }
    return 0;
}  

//输入 asdfdf(一串字符)回车然后再输入ctr……

#4


因为“规定”,操作系统的规定,和c、c++没关系。

#5


因为程序需要你按一个“确定”键,这时是Ctrl+Z就当做是确定键输入了
这时需要再一次按Ctrl+Z才能退出,不然还是可以继续输入字符的
个人觉得是这样的

#6


引用 4 楼 taodm 的回复:
因为“规定”,操作系统的规定,和c、c++没关系。


++

#7


该回复于2011-11-14 10:52:07被版主删除

#8


该回复于2011-11-14 10:52:06被版主删除

#9


那是控制台的截断操作吧
跟C++没有关系的

#10


二楼的是正解
我开始学习的时候也有过这样的困惑;
那个EOF是指函数的返回值,而不是 c 的值,

你可以测试下面的程序:

#include<stdio.h>
#include<stdlib.h>

int main()
{
  int a,b;
  b=scanf("%d",&a);
  printf("%d %d",a,b);
   
  system("pause");
  return 0;   
    

/*输入数字结果是1 字母是0 EOF(CTRL+z) 是-1 */

#11


我把getchar返回值给c了。。有区别吗。。我是想知道为什么单独输入^Z\n和在abc^Z\n这样输入,对^Z的处理有什么不同。和EOF没关系哈。。为什么前者能终止循环,后者不行。感觉和流的处理有关系,后者应该是把^Z当做流的终止符了,没有赋值给C,但是为什么前者没有当做终止符而是直接给C了呢?楼上各位大神求教啊。。
引用 10 楼 huangd29 的回复:
二楼的是正解
我开始学习的时候也有过这样的困惑;
那个EOF是指函数的返回值,而不是 c 的值,

你可以测试下面的程序:

#include<stdio.h>
#include<stdlib.h>

int main()
{
  int a,b;
  b=scanf("%d",&amp;a);
  printf("%d %d",a,b);
   
  system(……

#12


EOF 是scanf和getchar的返回值哈。你那样写肯定输一次不行,得输入两次

#13


引用 4 楼 taodm 的回复:
因为“规定”,操作系统的规定,和c、c++没关系。


LZ,我以前发过跟你差不多的帖子,我发的是50分,下面这个回答我给了他40分:

windows下输入完后完回车后按ctrl+z 再按回车。
linux/unix下输入完后按回车后按ctrl+d再按回车。
或者在命令行上通过管道把文件的内容进行计数。
program < test.txt 

#14


按下Ctr + z 还不能够退出循环吗?

#15


其实对这样的问题,我觉得没有必要去纠集。

EOF 就是 文件结尾。
实际的程序肯定是 直接文件操作的,不太可能,控制台手工输入的

真实的环境是文件输入,可定能 终止循环

#16


#17


^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环

#18


不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
 if (条件1) break;
 //...
 if (条件2) continue;
 //...
 if (条件3) return;
 //...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
whlie (!feof(f)) {
 a=fgetc(f);
 //...
 b=fgetc(f);//可能此时已经feof了!
 //...
}
而这样写就没有问题:
whlie (1) {
 a=fgetc(f);
 if (feof(f)) break;
 //...
 b=fgetc(f);
 if (feof(f)) break;
 //...
}
类似的例子还可以举很多。

#19


这个能不能用 ctrl + c 结束呢?

#20


引用 17 楼 selooloo 的回复:
^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环


我觉得这个兄弟有道理,^z只是一个标志,代表读取结束,比如输入ab^zcd,getchar读取缓冲区时候只读取到了ab和26,这个26可能是ctrl+z的码值,遇到^z就不读了,
如果你直接输入^z的话,就是告诉getchar缓冲区里第一个就是终止符,无数据。自然返回EOF了

#21


引用 20 楼 yuqangy 的回复:
引用 17 楼 selooloo 的回复:
^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环


我觉得这个兄弟有道理,^z只是一个标志,代……


++

#22


学习了! 确实很精彩! 
引用 18 楼 zhao4zhong1 的回复:
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
 if (条件1) break;
 //...
 if (条件2) continue;
 //...
 if (条件3) return;
 //...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语……

#23


我近天也是这个问题, 终于解决了, 哈哈~~~谢谢大家哈! 学习了!
引用 17 楼 selooloo 的回复:
^Z根本不会被getchar读取,对于a^Z缓冲区里有字符,所以getchar能正常工作,这时你在a^Z后面再键入别的字符比如a^Zafsfaa^Za^Za^Z结果也是一样,遇到^Z就不再读取了。
第二次^Z,缓冲区里无内容,getchar出错返回-1,这个-1恰好也是EOF的值,所以可以退出循环