使用C ++中的两个文件流处理异常

时间:2014-04-11 12:17:17

标签: c++ exception try-catch fstream

我正在使用Visual Studio 2012构建一个处理输入文件和输出文件的程序。

我这样实施:

ifstream inputFile;
ofstream outputFile;

inputFile.exceptions ( ifstream::failbit | ifstream::badbit );
try
{
    // some codes here
    inputFile.open(inputFileName.c_str());
    cout << "Input file opened" << endl;

    outputFile.open(outputFileName.c_str());
    cout << "Output file opened" << endl;
}
catch (ifstream::failure e)
{
    cerr << "Failed to open input file" << endl;
    return -1;
}
catch (ofstream::failure e)
{
    cerr << "Failed to open output file" << endl;
    return -1;
}   

发生编译错误:

error C2312: 'std::ios_base::failure' : is caught by 'std::ios_base::failure' at line 248

如何使用两个异常来源实现try-catch?

2 个答案:

答案 0 :(得分:3)

您的问题是ifstream::failureofstream::failure属于同一类型(从ios_base继承到它们),

由于它是同一个异常,编译器会抱怨。

顺便说一句,你应该catch by const reference以避免不必要的副本。

答案 1 :(得分:0)

如您所见,抛出的异常类型是相同的。但是,由于你的检查是在文件开头附近完成的,你可以毫无例外地做到,不是吗?像:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
  string inputFileName { "/notexists" };
  string outputFileName { "/notexistsandprobablynotwritable" };
  ifstream inputFile { inputFileName };
  if( !inputFile ) {
    cerr << "Failed to open input file" << endl;
    return -1;
  }
  cout << "Input file opened" << endl;
  ofstream outputFile { outputFileName };
  if( !outputFile ) {
    cerr << "Failed to open output file" << endl;
    return -1;
  }
  cout << "Output file opened" << endl;
}

或者,如果您确实需要例外,您可以在开放站点自己抛出不同的例外:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

template<typename Stream, typename Exception = typename Stream::failure>
  void try_open(Stream& s, string filename) {
      s.open(filename);
      if( !s )
        throw Exception( string("cannot open ")+filename );
  }

struct input_exception: ifstream::failure { input_exception(const string& s): ifstream::failure(s) {} };
struct output_exception: ofstream::failure { output_exception(const string& s): ofstream::failure(s) {} };

int main() {
  string inputFileName { "/notexists" };
  string outputFileName { "/notexistsandprobablynotwritable" };
  try {
    ifstream inputFile;
    try_open<ifstream, input_exception>(inputFile, inputFileName);
    cout << "Input file opened" << endl;
    ofstream outputFile;
    try_open<ofstream, output_exception>(outputFile, outputFileName);
    cout << "Output file opened" << endl;
  } catch(const output_exception& e) {
      cerr << "output exception!\n" << e.what() << "\n";
  } catch(const input_exception& e) {
      cerr << "input exception!\n" << e.what() << "\n";
  } catch(const exception& e) {
      cerr << "exception!\n" << e.what() << "\n";
  }
}