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

Handling exception(s) with two file stream in C++

本文关键字:文件 两个 处理 异常 C++      更新时间:2023-10-16

我正在使用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?

您的问题是ifstream::failureofstream::failure是相同的类型(从ios_base继承给它们),

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

顺便说一句,您应该通过const引用捕获,以避免不必要的副本。

正如您所看到的,抛出的异常类型是相同的。但是,由于您的检查是在文件打开时进行的,所以您可以毫无例外地进行检查,不是吗?类似:
#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";
  }
}