关于C++的异常检测的关键字主要有3个,分别是throw,try,catch。它们的作用如下:
throw用于抛出错误,throw invalid_argument("can't open file");
try用于尝试执行含有抛出错误的代码;
catch用于捕获对应类型的错误对象,catch (invalid_argument& e),由于包含在<stdexcept>中的错误类型是多态的,可以通过向上转型的方式,捕获更多不同类型的错误对象。比如catch (exception& e)可以捕获invalid_argument,和runtime_error类型的错误对象。
关于错误抛出的ReadFile函数如下所示:
void ReadFile(const string& filename, vector<string>& vec_str)
{
ifstream ifstr;
string mystr;
ifstr.open(filename);
if(ifstr.fail())
{
string error = "Unable to open " + filename;
throw invalid_argument(error);
}
while(getline(ifstr, mystr))
{
vec_str.push_back(mystr);
}
if(ifstr.eof()) ifstr.close();
else
{
string error = "Unable to readfile " + filename;
throw runtime_error(error);
}
}
在上面的代码中,通过执行if(ifstr.fail())来判断是否读取文件发生错误;通过执行if(ifstr.eof())来判断是否读取文件异常退出。
程序的try,catch部分写在了主函数里,如下所示:
int main()
{
vector<string> vec_str;
try
{
ReadFile("test.txt", vec_str);
}
catch(const exception& e)
{
cerr << e.what() << endl;
}
ReadVector(vec_str);
}
由于exception是invalid_argument和runtime_error的基类,而且是变量引用的形式,所以可以捕获invalid_argument和runtime_error类型的错误对象。
如果需要编写自己定义的异常类,主要只需要写两个函数,一是构造函数,一是what函数,如下:
class FileError: public exception
{
public:
FileError(string msg): error_msg(msg){};
virtual const char* what() const noexcept override {return error_msg.c_str();}
private:
string error_msg;
};
其中,c_str表示c类型的字符串,返回类型为cosnt char*。
程序的所有代码如下:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
using namespace std;
class FileError: public exception
{
public:
FileError(string msg): error_msg(msg){};
virtual const char* what() const noexcept override {return error_msg.c_str();}
private:
string error_msg;
};
void ReadFile(const string& filename, vector<string>& vec_str)
{
ifstream ifstr;
string mystr;
ifstr.open(filename);
//~ if(ifstr.fail())
//~ {
//~ string error = "Unable to open " + filename;
//~ throw invalid_argument(error);
//~ }
if(ifstr.fail())
{
string error = "Unable to open " + filename;
throw FileError(error);
}
while(getline(ifstr, mystr))
{
vec_str.push_back(mystr);
}
//~ if(ifstr.eof()) ifstr.close();
//~ else
//~ {
//~ string error = "Unable to readfile " + filename;
//~ throw runtime_error(error);
//~ }
}
void ReadVector(const vector<string>& vec_str)
{
for(auto ite = vec_str.begin(); ite < vec_str.end(); ++ite)
{
cout << *ite << endl;
}
}
int main()
{
vector<string> vec_str;
try
{
ReadFile("test1.txt", vec_str);
}
catch(const FileError& e)
{
cerr << e.what() << endl;
}
catch(...)
{
cerr << "error";
}
ReadVector(vec_str);
}