什么在这个文件流中抛出异常?

时间:2014-06-25 20:48:52

标签: c++ ifstream

我不知道输入文件流是什么引发了异常。我之前几乎没有遇到任何问题。

std::string accnts_input_file = "absolute_path/account_storage.txt";
std::string strLine;
std::ifstream istream;
istream.exceptions( std::ifstream::failbit | std::ifstream::badbit );

try
{
    istream.open( accnts_input_file.c_str() );

    while( std::getline( istream, strLine ) )
    {
        std::cout << strLine << '\n';
    }

    istream.close();
}
catch( std::ifstream::failure &e )
{
    std::cerr << "Error opening/reading/closing file" << '\n'
              << e.what()
              << std::endl;
}

我只打印它现在读取的行以尝试跟踪错误。它逐行读取文件并打印它们,然后抛出异常。例外的是basic_ios :: clear,我不明白。我认为ifstream :: failbit是抛出异常,因为当我只设置ifstream :: badbit时它不会抛出异常,但我无法弄清楚原因。我还尝试过(!istream.oef())&#39;以及大多数其他方法,而不是&#39; while(std :: getline(istream,strLine))&# 39;,但我一直得到同样的错误。

我确定它可能是一个显而易见的错过,但任何帮助都会受到赞赏。感谢

3 个答案:

答案 0 :(得分:8)

来自this std::getline reference

  

...
  a)输入的文件结束条件,在这种情况下,getline设置eofbit   ...
  3)如果由于某种原因没有提取任何字符(甚至没有丢弃的分隔符),则getline设置failbit并返回。

这意味着在文件结束时,该函数将设置为 eofbitfailbit。当您在设置failbit时要求获取异常时,库会抛出异常。

答案 1 :(得分:2)

当您尝试从流中读取但没有任何内容可供读取时,读取操作将失败(=在getline的第二个参数表示的变量中未插入任何字符),failbit已设置且在您的情况下为异常扔了。

使用while(!ifstream.eof())只有在您的文件不以例如换行符结束时才有用。仅当到达流的末尾时才设置eofbit,即,读出流的每个内容。但是如果文件以换行符结尾,则读取操作将失败,而不会在之前设置eofbit。

答案 2 :(得分:0)

可能的解决方案之一:

bool mygetline( std::istream &in, std::string &s )
{
    try {
        return std::getline( in, s );
    }
    catch( std::ifstream::failure & )
    {
         if( !in.eof() ) throw;
         return false;
    }
}

std::string accnts_input_file = "absolute_path/account_storage.txt";
std::string strLine;
std::ifstream istream;
istream.exceptions( std::ifstream::failbit | std::ifstream::badbit );

try
{
    istream.open( accnts_input_file.c_str() );

    while( mygetline( istream, strLine ) )
    {
        std::cout << strLine << '\n';
    }

    istream.close();
}
catch( std::ifstream::failure &e )
{
    std::cerr << "Error opening/reading/closing file" << '\n'
              << e.what()
              << std::endl;
}