C++笔记七(文件、异常)

1.文件操作

1.基本概念
原由:程序运行时数据都是临时数据,程序一旦运行结束便会被释放,通过文件可以将数据持久化。

C++中文件操作的头文件为< fstream >

文件类型分为两种:
其一,文本文件:文件以文本的ASCII码的形式存储在计算机中
其二,二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们

文件操作的三大类(class)
其一,ofstream 写操作
其二,ifstream 读操作
其三,fstream 读写操作

2.文本文件
写文件的步骤:
1>包含头文件 #include< fstream >
2>创建流对象 ofstream ofs;
3>打开文件 ofs.open(“文件路径”,打开方式) ;
4>写数据 ofs << “写入数据”;
5> 关闭文件 ofs.close();

文件打开方式:
ios::in       为读文件而打开文件
ios::out     为写文件而打开文件

ios::ate      初始位置:文件尾
ios::app       追加方式写文件
ios::trunc     如果文件存在那就先删除,再创建
ios::binary     二进制方式
注意:如果要配合使用打开方式,那就需要用|操作符
eg:ios::binary|ios::out

读文件的步骤:
1>包含头文件 #include< fstream >
2>创建流对象 ifstream ifs;
3>打开文件 ifs.open(“文件路径”,打开方式) ;
4>读数据 四种方式读取;(见下面代码,前三个中记忆一个)
5> 关闭文件 ifs.close();

  void test01()
{
	ofstream ofs;
	ofs.open("D:/C++demo/test.txt", ios::out);
	ofs << "hello,树先生!";
	ofs.close();
}
void test02()
{
	ifstream ifs;
	ifs.open("D:/C++demo/test.txt", ios::in);
	if (!ifs.is_open())
	{
		cout << "打开失败!" << endl;
		return;
	}
	//读数据方式1。>>操作符重载,一次读一行!
	char buf1[1024] = { 0 };	
	while (ifs >> buf1)
	{
		cout << buf1;
	}
	//读数据方式2
	char buf2[1024] = { 0 };
	while (ifs.getline(buf2,sizeof(buf2)))
	{
		cout << buf2 << endl;
	}
	//读数据方式3
	string buf3;
	while (getline(ifs,buf3))
	{
		cout << buf3 << endl;
	}
	//读数据方式4,效率太低不推荐
	char c;
	while ((c = ifs.get()) != EOF)	//EOF表示end of file文件尾
	{
		cout << c;
	}

	ifs.close();
}
int main()
{
	//test01();
	test02();
	return 0;
}

注意:对文件进行操作时可以少用string多用数组替代,并且打开方式里的路径是“/”。

3.二进制文件
对于二进制文件,打开方式指定为ios::binary

写文件,主要利用流对象调用成员函数write
函数原型:ostream& write(const char* buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间,len是读写字节数

读写实例如下:

class Person
{
public:
	char m_Name[64];
	int m_Age;
};

void test01()
{
	ofstream ofs;
	ofs.open("D:/C++demo/test1.txt", ios::out | ios::binary);
	//其实上面两步可以合成一步ofstream ofs("D:/C++demo/test.txt", ios::out | ios::binary);	//有构造函数
	Person p = { "张三",12 };	//想想结构体
	ofs.write((const char *)&p, sizeof(Person));
	ofs.close();
}
void test02()
{
	ifstream ifs;
	ifs.open("D:/C++demo/test1.txt", ios::in | ios::binary);
	if (!ifs.is_open())
	{
		cout << "打开失败!" << endl;
		return;
	}
	Person p1;
	ifs.read((char *)&p1, sizeof(Person));
	cout << "name:" << p1.m_Name << "\t" << "age:" << p1.m_Age << endl;
	ifs.close();
}
int main()
{
	//test01();
	test02();
	return 0;
}

2.异常

2.1基本概念
1> 异常处理机制分为两个主要部分:异常的鉴定与发出,异常的处理方式。
2> 基本步骤:异常出现后,程序的执行被暂停,异常处理机制开始搜索程序中有能力处理异常的地点,异常被处理后,程序从异常处理点接着执行下去。
3> 异常:大部分被抛出的异常都是特定的异常类(也许形成一个继承体系),有时也是一个整数、字符串等。

2.2抛出异常
1> 异常抛出关键字:throw
2> 抛出异常中的异常是一个对象

2.3捕获异常
1> 捕获异常的关键字:catch
2> 语法:catch(){},小括号内放一个对象,用于和throw抛出的异常匹配;花括号用于处理异常。
3> 过程:我们可以通过一连串的或者单条catch子句去捕获抛出来的异常对象,当有多条catch时,抛出的异常会依次与catch对比,如果匹配了,便执行花括号内的语句,执行完后再由正常程序重新接手,从异常处理点继续向下执行。倘若异常没能得到完整的处理,我们可以继续在花括号内加个throw;,以寻求其他catch子句的协助,再一次抛出异常。
4> 再次抛出:catch子句中最后加个throw;即可。
5> 一网打尽:catch(…),不管抛出什么异常,都会被捕获。

2.4提炼异常
1> 语法:try{}
2> 处理过程:catch子句应该与try一起,try内有任何异常发生,抛出由catch处理。如果处理不了,没有匹配的,那就终止try块所在函数的执行,在函数调用端去寻找匹配的catch语句,如果找不到就一直上溯,直到找到为止,如果到了main()还找不到,那就调用标准库的terminate()——中断整个程序。(详细见《Essential C++》P196)
示例:

void test()
{
	int arr[5];
	int index = 0;
	cin >> index;
	try
	{
		if (index > 4 || index < 0)
		{
			throw(-1);
		}
	}
	catch (int i)
	{
		cout << "下标不合法!" << endl;
		throw;
	}
	cout << "end!" << endl;
}

2.5局部资源管理
1> 问题:倘若在某个函数内使用new开辟了内存,在函数结尾处delete掉了,但是new与delete之间出现了异常,而且未得到解决,那么显然delete是不会被执行的。这就造成了内存泄漏!
2> 解决方案1:导入try—catch,而且catch是一网打尽,花括号内执行释放资源的操作。此方案虽然可以解决问题,但是释放资源的语句要写两遍!
3> 解决方案2:我们一般把资源请求放在构造函数中,资源释放就放到析构函数中。C++保证函数结束前会调用所有局部对象的析构函数。所以可以使用局部对象。如果是在堆开辟空间那就用智能指针就好了。

2.6标准异常
1> 标准库定义了一套异常类体系,其根部是一个名为exception的抽象类,里面含有一个what()的虚函数,会返回const char *,用于表明异常。比如当new表达式无法再分配到足够内存时就会抛出bad_alloc异常,该异常就是派生自exception基类,也有自己的what()函数。
2> 使用:我们可以将自己写的异常类继承exception,这样当抛出我们写的异常类对象时,就会被所有打算捕获抽象基类exception的程序代码捕获,所以我们可以让那些程序代码认识这个类,也不必使用一网打尽的方式捕获所有异常了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值