C++的异常检测方法(以文件读取为例)

  • Post author:
  • Post category:其他


关于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);	
}



版权声明:本文为makesifriend原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。