[英]Don't understand how .eof () works in c++
我最近在课堂上开始使用文件。 在做作业时,我无法真正理解.eof()。
我们正在编码的程序应该执行以下操作:该程序要求您提供文件名,将其打开,然后读取每个字符并计算每个单词。 最后,它显示了单词的平均长度。
发生的情况是:每当我打开带有以点号结尾的文本的文件时,它都能正常工作,平均值是正确的。 但是,当文本不以点结尾时(例如:9 8 7 6 5 4 3 2 1点火),则表明没有单词。 我一直在互联网上搜索,但只发现File End常量通常为-1
。 我只是想弄清楚它是如何工作的。 谢谢
代码如下:
bool isSeparator (char lletra){ //Com que són caràcters anglesos no hem de tenir en compte els accents
//Pre: cert
//Post: retorna cert si lletra és un separador, fals altrament -- els números són entesos com separadors
bool separador = true;
if(lletra>='a' and lletra<='z')
separador = false;
else if(lletra>='A' and lletra<='Z')
separador = false;
else {
separador = true;
}
return separador;
}
void calculateNumbers (string fileName){
ifstream openFile (fileName.c_str());
char lletra; //Iniciem la primera variable
openFile>>lletra;
double wordCounter, average, wordLength, totalLength;
char auxiliar = ' ';
wordCounter = average = wordLength = totalLength = 0;
while (not openFile.eof()){ //Mentre no trobi el final, que continui mirant lletres
if (not isSeparator(lletra)){
wordLength++;
auxiliar = lletra;
} else if (isSeparator (lletra) and not isSeparator(auxiliar)){
wordCounter++;
totalLength+=wordLength;
wordLength = 0;
auxiliar = lletra;
}
openFile>>lletra;
}
cout<<setprecision(3);
cout<<fixed;
average = totalLength/wordCounter;
if (average==0){
cout<<"Mitjana longitud mot: cap mot!";
} else {
cout<<totalLength<<" "<<wordCounter<<endl;
cout<<"Mitjana longitud mot: "<<average<<endl;
}
cout<<openFile.eof();
}
有些东西在加泰罗尼亚语中。 如果有什么你不懂的就问我。
此问题说明.eof()
工作方式。
您的代码实际上可以正确读取文件(尽管不使用推荐的样式)。 lletra
存储从文件读取的最新字符,并且一旦字符用完,就不会输入循环主体。
您的代码仅在遇到分隔符时使wordCounter
递增。 因此,当文件具有时.
, wordCounter
变为1
。 如果文件没有.
(并且没有其他分隔符)即使文件中包含“单词”,它也始终为0。
这使行average = totalLength/wordCounter;
除以零会导致不确定的行为。
解决此问题的方法:您可以添加逻辑,以便如果文件未以分隔符结尾,则假装文件确实以分隔符结尾,以便将最后一个单词视为一个单词。 例如,循环退出后,检查lletra
,如果它不是分隔符,则增加字计数器。
如果离散变量是整数类型而不是double
类型,那也更好。
注意 如果您实际上是按照“ word”的正常含义来计算文件中的单词数,那么您使用的方法就没有用,因为您无法分辨foo bar
和foobar
之间的区别。
如果要使lletra
捕获所有空格,则需要将openFile>>lletra
更改为openFile.get(lettra)
。 >>
运算符跳过空格。 如果您使用我的第一段中的链接中的推荐样式,则只需要在一个位置进行此更改,而无需更改代码中的两个位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.