C++ scanf 函数与EOF 浅析

原创 2015年07月07日 22:22:38
【摘要】

常常遇到这段代码, while(scanf("%d",&num)!=EOF){...} ,对于 EOF 以及 scanf 函数的返回值始终没有好好研究过,本文将对这个问题进行一下简单的剖析。


【正文】


【scanf 函数返回值】
1.scanf()函数有返回值且为int型。
2.scanf()函数返回的值为:正确按指定格式输入变量的个数;也即能正确接收到值的变量个数。
3.当scanf函数的第一个变量格式不正确时返回值为0,即,当scanf函数的第n个变量格式不正确时,返回值为n-1;

4.如果在scanf的时候在终端输入ctrl+d,或者直接输入异常时,scanf的返回值将是-1。


【EOF是什么】
EOF是end of file的缩写,表示"文字流"(stream)的结尾。这里的"文字流",可以是文件(file),也可以是标准输入(stdin)。很自然地,我就以为,每个文件的结尾处,有一个叫做EOF的特殊字符,读取到这个字符,操作系统就认为文件结束了。但是,后来我发现,EOF不是特殊字符,而是一个定义在头文件stdio.h的常量,一般等于-1。

#define EOF (-1)


在Linux系统之中,EOF根本不是一个字符,而是当系统读取到文件结尾,所返回的一个信号值(也就是-1)。至于系统怎么知道文件的结尾,资料上说是通过比较文件的长度。
所以,处理文件可以写成下面这样:
  int c;
  while ((c = fgetc(fp)) != EOF)
      {
    do something
  }
但是,这样写也有问题。fgetc()读取文件的最后一个字符以后,C语言的feof()函数依然返回0,表明没有到达文件结尾;只有当fgetc()向后再读取一个字符(即越过最后一个字符),feof()才会返回一个非零值,表示到达文件结尾。

所以,按照上面这样写法,如果一个文件含有n个字符,那么while循环的内部操作会运行n+1次。所以,最保险的写法是像下面这样:

  int c = fgetc(fp);
  while (c != EOF) 
      {
    do something;

    c = fgetc(fp);
  }
  if (feof(fp)) {
    printf("\n End of file reached.");
  } else {
    printf("\n Something went wrong.");
  }
除了表示文件结尾,EOF还可以表示标准输入的结尾。
  int c;
  while ((c = getchar()) != EOF) 
      {
    putchar(c);
  }
但是,标准输入与文件不一样,无法事先知道输入的长度,必须手动输入一个字符,表示到达EOF。
Linux中,在新的一行的开头,按下Ctrl-D,就代表EOF(如果在一行的中间按下Ctrl-D,则表示输出"标准输入"的缓存区,所以这时必须按两次Ctrl-D);Windows中,Ctrl-Z表示EOF。(顺便提一句,Linux中按下Ctrl-Z,表示将该进程中断,在后台挂起,用fg命令可以重新切回到前台;按下Ctrl-C表示终止该进程。)
那么,如果真的想输入Ctrl-D怎么办?这时必须先按下Ctrl-V,然后就可以输入Ctrl-D,系统就不会认为这是EOF信号。Ctrl-V表示按"字面含义"解读下一个输入,要是想按"字面含义"输入Ctrl-V,连续输入两次就行了。

C++为什么不提倡使用scanf和printf函数

C++为什么不提倡使用scanf和printf函数 最重要的原因当然是C++提供了流对象‘>>’和‘’,它们代表了新观念。流对象能输出对象,而printf函数和scanf函数不能。此外,起码还有...
  • chenshuzhenteacher
  • chenshuzhenteacher
  • 2012年10月20日 10:44
  • 9555

【C/C++】scanf的用法 神器

详细请见:http://www.360doc.com/content/07/0213/11/17255_365683.shtml scanf() 1、可选的格式 %*X  代表可以跳过几个x类型的...
  • phoenixwsl
  • phoenixwsl
  • 2011年12月29日 20:31
  • 4431

C++ scanf()输入string类型变量

步骤: 1、string tmp;//声明 2、tmp.resize(11);//限定大小 3、scanf("%s", &tmp[0]);//输入 输入数据中,超出指定个数的部分会...
  • wxf2012301351
  • wxf2012301351
  • 2017年05月18日 00:37
  • 1646

C/C++ scanf 函数中%s 和%c 的简单区别

首先声明:在键盘中敲入字符后,字符会首先保存在键盘缓冲区中供scanf函数读取(scanf,getchar等函数是读取缓冲区,getch函数是读取的控制台信息,即为直接从键盘读取)。另外特别注意键盘上...
  • u013630349
  • u013630349
  • 2015年08月18日 09:29
  • 3378

C++中getline与C中scanf、gets小结

 getline()的原型是istream& getline ( istream &is , string &str , char delim ); 其中 istream &is 表示一个输入...
  • cr2066
  • cr2066
  • 2016年08月04日 00:14
  • 721

C++之EOF()

    fstream流的eof()判断有点不合常理    按常理逻辑来说,如果到了文件末尾的话,eof()应该返回真,但是,C++输入输出流如何知道是否到末尾了呢?    原来根据的是:如果fin>...
  • ixidof
  • ixidof
  • 2009年11月07日 13:52
  • 19033

C++文件操作之eof函数问题

关于eof函数       fstream / ifstream / ofstream 类中的 成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int ...
  • pear_zi
  • pear_zi
  • 2011年10月29日 17:37
  • 5511

C++——EOF是个什么东西?

EOF是end of file的缩写,表示”文字流”(stream)的结尾。这里的”文字流”,可以是文件(file),也可以是标准输入(stdin)。 EOF不是特殊字符,而是一个定义在头文件stdi...
  • sinat_36053757
  • sinat_36053757
  • 2017年03月26日 22:56
  • 719

如何解决C++中用eof()多读一次

如何解决C++中用eof()多读一次 0条评论  在C++中文件的读取时,如果用 ifstream fin("xxx.xxx");...
  • jfkidear
  • jfkidear
  • 2015年10月28日 17:06
  • 1734

C++ eof()函数陷阱

C++中用eof()检查是否到达文件结尾 分类: C 编程 2007-06-26 11:15 到达文件结尾有两种可能的解释: 一是当程序从一个文件读取数据时,...
  • wangran51
  • wangran51
  • 2012年12月20日 16:49
  • 1320
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ scanf 函数与EOF 浅析
举报原因:
原因补充:

(最多只允许输入30个字)