与 fileIO 中的空格混淆

Confusion with spaces in fileIO

我有很好的输入文件,如下所示:

734 220 915 927 384 349 79 378 593 46 2 581 500 518 556 771 697
571 891 181 537 455 

和看起来像这样的错误输入文件:

819 135 915 927 384 349 79 378 593 46 2 581 500 518 556 771 697
551 425 815 978 626 207 931 ABCDEFG 358 16 875 936 899 885 195 565
571 891 181 537 110 

两个文件末尾的最后一个整数后面都有一个 space。我正在尝试用 C++ 编写一个脚本,它将读取所有整数,除非像第二个示例中那样存在 char/string,在这种情况下它会提醒我这一点。我试过这样写:

int main()
{
int n;
bool badfile = false;
ifstream filein("data.txt");

while (!filein.eof())
{
    filein >> n;    
    if(filein.fail())
    {
        cout << "Not an integer." << endl;
        badfile = true;
        break;  
    }   
    cout << n << " ";   
}

cout << endl << "file check: " << badfile << endl;
}

filein.fail() 是由好文件末尾的 space 以及坏文件中的 char/string 触发的。那么我该如何设置它以使其忽略白色 spaces 呢?为什么它只有在末尾有 space 时才会失败,而不是完全失败 space 或完全忽略它们?

主要问题是如何在流上测试 eof()...它仅在 后设置 输入尝试尝试读取更多字符文件结尾。首先使用 std::ws 来消耗空白意味着 eof 检测可以是可靠的:如果你不是那么在 eof() 你知道你在一些非空白输入应该是一个数字- 如果不是你输入的内容有误。

建议代码:

#include <iostream>
#include <fstream>
#include <iomanip>

int main()
{
    if (ifstream filein("data.txt"))
    {
        while (filein >> std::ws && !filein.eof())
        {
            int n;
            if (filein >> n)
                cout << n << ' ';
            else
            {
                std::cerr << "error in input\n";
                exit(EXIT_FAILURE);
            }
        }
        std::cout << '\n';
    }
    else
        std::cerr << "unable to open data.txt\n";
}

下面显示了一个替代方法,它可能更容易理解,但并不完全可靠。问题是尽管有错误的输入,例如尾随 -+,您仍然可以到达 EOF,因为在尝试读取数字时会消耗它,但它本身不足以构成成功的解析的一个数字。只有已知文件有一个 '\n' 终止最后一行,这才是可靠的:

        int n;
        while (filein >> n)
            cout << n << " ";   
        filein.clear();  // remove the error state
        if (filein.peek() != istream::traits_type::eof())
        {
            // while didn't reach EOF; must be parsing error
            std::error << "invalid input\n";
            exit(EXIT_FAILURE);
        }

我建议

ifstream filein("data.txt");
while (filein >> n)
    cout << n << " ";
if (filein.fail()) {
    cout << "Not an integer." << endl;
    badfile = true;
}
cout << endl << boolalpha << badfile << endl;