我最近在课堂上开始使用文件。做作业时,我真的听不懂.eof()。
我们正在编码的程序应该执行以下操作:该程序要求您提供一个文件名,将其打开,然后读取每个字符并计算每个单词。最后显示了单词的平均长度。
会发生什么:
每当我打开带有以点号结尾的文本的文件时,它都能正常工作,平均值是正确的。但是,当文本不以点结尾时(例如:9 8 7 6 5 4 3 2 1点火),则表明没有单词。
我一直在互联网上搜索,但只发现文件常量结尾通常是-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();
}
有些东西在加泰罗尼亚语中。如果有什么你不懂的就问我。
答案 0 :(得分:1)
This question解释了.eof()
的工作原理。
您的代码实际上可以正确读取文件(尽管不使用推荐的样式)。 lletra
存储从文件中读取的最新字符,一旦字符用完,就不会输入循环主体。
您的代码遇到分隔符时只会递增wordCounter
。因此,当文件具有.
时,wordCounter
变为1
。如果文件中没有.
(也没有其他分隔符),则即使文件中包含“单词”,它也始终为0。
这使行average = totalLength/wordCounter;
除以零会导致不确定的行为。
要解决此问题:您可以添加逻辑,以便如果文件未以分隔符结尾,则假装文件确实以分隔符结尾,以便将最后一个单词视为一个单词。例如。循环退出后,检查lletra
,如果它不是分隔符,则增加字计数器。
如果离散变量是整数类型而不是double
,那就更好了。
NB。如果您实际上是按照“ word”的正常含义来计算文件中的单词数,那么您使用的方法就没有用,因为您无法分辨foo bar
和{{1 }}。
如果要让foobar
捕获所有空格,则需要将lletra
更改为openFile>>lletra
。 openFile.get(lettra)
运算符将跳过空格。如果您在我的第一段中使用链接中推荐的样式,则只需要在一个位置进行此更改,而无需更改代码中的两个位置。