简体   繁体   English

不了解.eof()如何在c ++中工作

[英]Don't understand how .eof () works in c++

I have started working with files recently in class. 我最近在课堂上开始使用文件。 When doing my homework, I can't really understand .eof(). 在做作业时,我无法真正理解.eof()。

The program which we are coding should do the following: the program asks you for a file name, opens it, and reads every character and counts every word. 我们正在编码的程序应该执行以下操作:该程序要求您提供文件名,将其打开,然后读取每个字符并计算每个单词。 In the end it shows the average length of the words. 最后,它显示了单词的平均长度。

What happens is: Whenever I open a file with a text that ends with a dot, it works correctly, the average is correct. 发生的情况是:每当我打开带有以点号结尾的文本的文件时,它都能正常工作,平均值是正确的。 However, when the text does not end with a dot (for example: 9 8 7 6 5 4 3 2 1 Ignition), it shows that there are no words. 但是,当文本不以点结尾时(例如:9 8 7 6 5 4 3 2 1点火),则表明没有单词。 I've been searching through the internet and I've only found that the End of File constant is normally -1 . 我一直在互联网上搜索,但只发现File End常量通常为-1 I'm just trying to figure out how it works. 我只是想弄清楚它是如何工作的。 Thanks 谢谢

The code is the following: 代码如下:

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();
}

Some of the things are in catalan. 有些东西在加泰罗尼亚语中。 If there's anything you don't understand just ask me. 如果有什么你不懂的就问我。

This question explains how .eof() works. 此问题说明.eof()工作方式。

Your code actually reads the file correctly (although does not use recommended style). 您的代码实际上可以正确读取文件(尽管不使用推荐的样式)。 The lletra stores the latest character read from the file and the loop body is not entered once the characters have run out. lletra存储从文件读取的最新字符,并且一旦字符用完,就不会输入循环主体。


Your code only increments wordCounter when it encounters a separator. 您的代码仅在遇到分隔符时使wordCounter递增。 So when the file has . 因此,当文件具有时. , wordCounter becomes 1 . wordCounter变为1 If the file has no . 如果文件没有. (and no other separator) it's always 0 even though the file had a "word" in it. (并且没有其他分隔符)即使文件中包含“单词”,它也始终为0。

This makes the line average = totalLength/wordCounter; 这使行average = totalLength/wordCounter; causes undefined behaviour by dividing by zero. 除以零会导致不确定的行为。

To fix this: you could add logic so that if the file does not end in a separator, then pretend that it did, so that you count the last word as a word. 解决此问题的方法:您可以添加逻辑,以便如果文件未以分隔符结尾,则假装文件确实以分隔符结尾,以便将最后一个单词视为一个单词。 Eg after the loop exits, check lletra and if it's not a separator then increment the word counter. 例如,循环退出后,检查lletra ,如果它不是分隔符,则增加字计数器。

Also it would be better if the discrete variables were integer types instead of double . 如果离散变量是整数类型而不是double类型,那也更好。


NB. 注意 If you are actually trying to count the number of words in the file , by the normal meaning of "word", then the method you are using is not useful because you can not tell the difference between foo bar and foobar . 如果您实际上是按照“ word”的正常含义来计算文件中的单词数,那么您使用的方法就没有用,因为您无法分辨foo barfoobar之间的区别。

If you want to make lletra catch all the spaces then you need to change openFile>>lletra to openFile.get(lettra) . 如果要使lletra捕获所有空格,则需要将openFile>>lletra更改为openFile.get(lettra) The >> operator skips spaces. >>运算符跳过空格。 If you use the recommended style from the link in my first paragraph then you only need this change in one place, rather than changing both places in the code as it stands. 如果您使用我的第一段中的链接中的推荐样式,则只需要在一个位置进行此更改,而无需更改代码中的两个位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM