与fileIO中的空格混淆

Confusion with spaces in fileIO

本文关键字:空格 fileIO      更新时间:2023-10-16

我有一个好的输入文件,看起来像这样:

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++中写一个脚本,将读取所有的整数,除非有一个字符/字符串在第二个例子中,在这种情况下,它会提醒我。我试着这样写:

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()是由好文件末尾的空格和坏文件中的字符/字符串触发的。我怎么设置它,让它忽略空白呢?为什么只有在末尾有空格时才会失败,而不是在所有空格都失败或完全忽略它们?

主要问题是如何在流上测试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 inputn";
                exit(EXIT_FAILURE);
            }
        }
        std::cout << 'n';
    }
    else
        std::cerr << "unable to open data.txtn";
}

下面出现了一个替代方案,它可能更容易理解,但不是完全可靠。问题是,尽管输入错误,如末尾的-+,您仍然可以达到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 inputn";
            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;