与fileIO

时间:2015-07-21 03:20:38

标签: c++ file-io whitespace

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

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 

两个文件末尾的最后一个整数后面有一个空格。我正在尝试用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()是由一个好文件末尾的空格以及一个坏文件中的char / string触发的。那么如何设置它以便忽略空格呢?为什么只有在最后有一个空格而不是在所有空格中失败或者完全忽略它们时它才会失败?

2 个答案:

答案 0 :(得分:1)

主要问题是如何在流上测试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);
        }

答案 1 :(得分:0)

我建议

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