C++ fstream.eof() 的问题

一道题目要求从txt文件中统计大写字母的个数,用 * 的多少来表示频数高低。
我新建了一个hello.txt文件,内容如下
//hello.txt
A B C D E
// file end
编写程序如下:
//count.cpp
#include<iostream>
#include<fstream>
using namespace std;
fstream in,out;
char ch;
int cnt[26]={0};//用于存放字母个数
int maxsum=0;//用于记录字母出现的最高频率
int main()
{
in.open("hello.txt",ios::in);//打开文件
while(!in.eof())
{
in>>ch;
if(ch>='A'&&ch<='Z')
cnt[ch-'A']++;//所有字母频率统计
}
in.close();//关闭文件
for(int i=0;i<26;i++)
{
if(cnt[i]>maxsum)
maxsum=cnt[i];//找出最高频率;
}
out.open("result.txt",ios::out);//建立文件存放统计结果
for(int i=maxsum;i>0;i--)
{
for(int j=0;j<26;j++)
{
if(cnt[j]>=i)
out<<'*'<<' ';
else
out<<' '<<' ';
}
out<<endl;
}
for(char cha='A';cha<='Z';cha++)
out<<cha<<' ';
out<<endl;
for(int i=0;i<26;i++)//输出频数
out<<cnt[i]<<' ';
out<<endl;
out.close();
system("pause");
return 0;
}
// file end

输出结果如下:
//result.txt
*
* * * * *
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// file end
(贴在网页上字符有些无法对齐)

问题是hello.txt文档中ABCDE五个字符只出现一次,而最后一个字符统计频数却多了一个。试了好几次,总是最后一个字符多统计一次。这说明while(!in.eof())语句在统计完最后一个字符后又循环了一次,这是怎么回事呢?

第1个回答  2014-08-22
原因是在读出最后一个字符时,in.eof()还是为假的,只当读过最后一个字符再读(读不成功)时in.eof()才变为真。由于最后一次没有读取成功,ch保持原值,所以最后一个字符被多算一次。
读取文件的操作一般采用所谓N+1/2循环结构,即:将
while(!in.eof())
{
in>>ch;
if(ch>='A'&&ch<='Z')

cnt[ch-'A']++;//所有字母频率统计
}

循环改为:
in>>ch; //...
while(!in.eof())
{
if(ch>='A'&&ch<='Z')
cnt[ch-'A']++;//所有字母频率统计
in>>ch; //...该语句比循环体中其它语句多执行一次
}本回答被提问者采纳

c++ fstream问题
前面读到文件末尾了eof 状态,文件在错误状态下面拒接写入内容了,需要clear()清除一下错误状态才行。你把这个加到第2个while 循环前面就可以了 while(!file.eof ) getline(file,s1) ; cout<<s1<<endl;}if (!file.good()) { file.clear(); \/\/清除前面eof错误状态} ...

c++中文件打开用了eof()后,为什么文件就再也打不开了啊??
eof()函数的设定是因为遇到文件尾了,EOF其实是-1值,当遇到文件末尾,则设置eof,并且返回eof()为true,然后对象不再读取文件,也就是输入流被截断 可以用fstream对象的clear来清除 你可以用iofile.clear();来重新设置

c++中关于eof()函数的一个问题
在open成功后不会对 fstream中状态进行操作,而open失败的话会设置_MyState为failbit,并且在close操作时如果本身是空文件,也会设置state为failbit,这样造成一次失败之后的其他很多操作都是失败的,因为很多fstream操作会先判断state;而clear函数是将fstream状态重置为goodbit ...

C++如何实现多组测试数据,处理到文件结束
fstream类有两种子类 分别是用于读出文件的ifstream类 以及用于写入文件ofstream类 在使用是应加入引用 : #include <fstream> 注意该头文件使用std命名空间 还应该加入语句 :using namespace std;使用的使用应该创建一个文件流对象 比如读入一个文件可以使用下列语句:ifstream File;char *FileName;char D...

C++读取二进制代码 即读出来是0和1
C++是文件输入输出流来读写文件的 下面给出例子C++文件流:fstream\/\/ 文件流 ifstream \/\/ 输入文件流 ofstream \/\/ 输出文件流 \/\/创建一个文本文件并写入信息 \/\/同向屏幕上输出信息一样将信息输出至文件 include<iomanip.h> include<fstream.h> void main(){ ofstream f1("d:\\\\me.txt");\/\/...

C++中!file.eof()什么意思?
代码要贴完整。eof()函数返回文件指针是否已到末尾,是返回true。一般这么用的 while(!file.eof()) { file.read(ch);}

谁能详细给我讲讲C++ eof() fail() 怎么用看C++plumer plus第五版...
C语言中常利用下面这种方法,来判断输出文件内容。例:while ((c = fgetc(fp)) != EOF) { putchar (c);} 那么在C++中,这种方式便得到了简化,因为有一个eof()函数到文件结尾可以返回true,而之前返回的均为false,下面的while语句也从while(true)->while(false),从而循环结束。例:fstream a;...

C++读取二进制文件问题
c\/c++从来是这样,刚好读到文件尾的时候不会有任何反应 在文件末端再读取一次,读取失败的情况下in.eof()会返回真,c的FILE也是同样的情况 你可以这么读 include <fstream> include <iostream> using namespace std;int main(){ ifstream in;in.open("book.dat",ios_base::in|ios_base::binary);...

C++中函数 ofstream outfile,文件路径名的问题
一、ASCII 输出 为了使用下面的方法, 你必须包含头文件<fstream.h>(译者注:在标准C++中,已经使用<fstream>取代< fstream.h>,所有的C++标准头文件都是无后缀的。)。这是 <iostream.h>的一个扩展集, 提供有缓冲的文件输入输出操作. 事实上, <iostream.h> 已经被<fstream.h>包含了, 所以你不必...

C++ 这里应该怎样使用feof()函数。
你用的是c++标准库中的输入输出类,而feof是c标准库的函数。c++标准库的ifstream没有提供成员函数能够得到C的文件指针FILE*,所以不能用feof来检测文件末尾。这里你的循环条件已经保证了在文件末尾时跳出。如果想要在ifstream上测试文件末尾,可以用eof成员函数。

相似回答