在文件处理中读取额外的一行

One extra line being read in file handling

我正在尝试从 C++ 中的文本文件中获取行数和字数。但是编译器正在读取额外的一行。

#include <iostream>
#include<fstream>
using namespace std;

int main(void)
{
    ifstream f;
    string name;
    char a;
    int line, words;
    line = 0;
    words = 0;


    f.open("file.txt");

    while (f) {
        f.get(a);


        if (a == '\n')
        {
            line++;
            words++;
        }

        if (a == ' ')
        {
            words++;
        }

    }
    f.close();
    cout << "Number of words in file : " << words << endl;
    cout << "Numbers of lines in the file : " << line << endl;
}

输出:-

Number of words in file : 79
Numbers of lines in the file : 3

file.txt:-

This C++ Program which counts the number of lines in a file. The program creates an input file stream, reads a line on every iteration of a while loop, increments the count variable and the count variable is printed on the screen.
Here is source code of the C++ program which counts the number of lines in a file. The C++ program is successfully compiled and run on a Linux system. The program output is also shown below.

我很困惑为什么要多读一行。请帮忙。

因为你没有检查stream是什么状态所以f.get(a) returns.

您没有检查 f.get() 是成功还是失败。当它确实失败时,a 不会更新,并且您还没有打破循环,因此您最终会再次对 aprevious 值进行操作。然后 next 循环迭代检测到失败并中断循环。

改变这个:

while (f) {
    f.get(a);
    ...
}

改为:

while (f.get(a)) {
    ...
}

话虽这么说,但您也没有考虑到文件中的最后一行可能不以 '\n' 结尾,如果不是,则您不算该行。而且,您假设每一行总是至少有 1 个单词,因为您在每个 '\n' 上递增 words,即使对于其中没有单词的行也是如此。

我建议使用std::getline()来读取和计算行数,使用std::istringstream来读取和计算每行中的单词数,例如:

#include <fstream>
#include <sstream>
#include <string>
#include <cctype>
using namespace std;

int main(void)
{
    ifstream f;
    string line, word;
    int lines = 0, words = 0;

    f.open("file.txt");

    while (getline(f, line))
    {
        ++lines;
        std::istringstream iss(line);
        while (iss >> word) {
            ++words;
        }
    }

    f.close();

    cout << "Number of words in file : " << words << endl;
    cout << "Numbers of lines in the file : " << line << endl;
}