主要的编程目的:
1.掌握try-throw-catch异常处理机制;
2.掌握使用异常处理机制处理程序中常见的异常;
3.了解标准异常处理类
实验一:
阅读程序,程序给出了4种不同输入情况下的4种不同输出结果,请对这4种输出结果做出你的解释。
#include <cmath>
#include <iostream>
using namespace std;
struct Res
{
float x1, x2;
};
Res resolution(int a, int b, int c) throw(int);
int main()
{
int a, b, c;
Res r;
cout << "Input a, b,c :";
cin >> a >> b >> c;
try //代码保护段
{
r = resolution(a, b, c);
cout << "x1=" << r.x1 << "\tx2=" << r.x2 << endl;
}
catch (int) {
cerr << "求负数平方根异常" << endl;
}
catch (...) {
cerr << "unexpected or rethrow exception!" << endl;
}
cout << "That is end" << endl;
return 0;
}
float quotient(int a, int b) throw(char *)
{
if (b == 0)
throw("除数为0异常!"); //抛出异常
else
return a / (float)b;
}
Res resolution(int a, int b, int c)
{
Res tmpr;
try
{
if (a == 0 && b != 0)
{
tmpr.x1 = tmpr.x2 = quotient(-c, b);
return tmpr;
}
if (b*b - 4 * a*c<0)
throw -1; //抛出int类型异常
tmpr.x1 = quotient(-b + sqrt(b*b - 4.0*a*c), 2 * a);
tmpr.x2 = quotient(-b - sqrt(b*b - 4.0*a*c), 2 * a);
cout << "That is ok" << endl;
return tmpr;
}
catch (char *ErrS)
{
cerr << ErrS << endl;
throw;
}
//cout << "That is end......" << endl;
}
2、
#include<iostream>
#include<cmath>
#include<stdexcept>
using namespace std;
//给出三角形三边长,计算三角形面积
double area(double a, double b, double c)throw(invalid_argument)
{
//判断三角形边长是否为正
if (a <= 0 || b <= 0 || c <= 0)
……………………… //抛出invalid_argument异常
//判断三边长是否满足三角不等式
if (a + b <= c || b + c <= a || c + a <= b)
……………………… //抛出invalid_argument异常
//计算三角形面积
double s = (a + b + c) / 2;
return sqrt(s*(s - a)*(s - b)*(s - c));
}
int main()
{
double a, b, c;//三角形三边长
cout << "请输入三角形的边长:";
cin >> a >> b >> c;
try {
double s = area(a, b, c);//尝试计算三角形面积
cout << "Area:" << s << endl;
}
catch (exception &e) {
cout << "Error:" << e.what() << endl;
}
return 0;
}
结果(一)
解释:代码执行到r=resolution(a,b,c)时,调用函数Res resolution(a,b,c),执行到函数中的try语句块,由于a=1,b=2不符合a==0&&b!=0条件,跳过if语句块的内容,又判断输入的a,b,c满足b*b-4*a*c<0,所以执行throw -1语句,执行异常-1,由于-1是int 类型,与catch(int)精确匹配,代码跳转到执行catch(int)的语句块,在屏幕上显示出求负数的平方根异常,跳过catch(…)执行输出That is end。
结果(二)
解释:代码执行到r=resolution(a,b,c)时,调用函数Res resolution(a,b,c),执行到函数中的try语句块,由于a=0,b=0不满足a==0&&b!=0条件,跳过if语句块的内容,又判断输入的a,b,c不满足b*b-4*a*c<0,跳过throw -1语句,向下执行到tmpr.x1=quotient(-b+sqrt(b*b-4*a*c),2*a),调用函数float quotient(int a,int b)thorw(char*),判断b==0条件符合,执行语句throw(“除数为0异常!”),与catch(char*)精确匹配,程序跳到catch(char*ErrS)语句块中执行cerr<<ErrS<<endl;输出除数为0异常!,执行到throw语句与catch(…)精确匹配,输出unexpected or rethrow exception!,最后执行cout<<”That is end”<<endl,输出That is end,执行到return 0程序结束。
结果(三)
解释:代码执行到r=resolution(a,b,c)时,调用函数Res resolution(a,b,c),执行到函数中的try语句块,由于a=0,b=2满足a==0&&b!=0条件,执行if语句块的内容,调用函数quotient(a,b),程序跳转到float quotient(a,b)throw(char*),又判断输入的b==0不满足条件,跳过throw (“除数为0异常!)语句,执行return a/(float)b语句,然后得到结构tmpr.x1=tmpr.x2,返回tmpr,把tmpr赋值给r,最后执行到cout<<”x1=”<<r.x1<<”\tx2=”<<r.x2<<endl语句,在屏幕上输出x1=-1.5,x2=-1.5,又无异常,跳过所有catch语句块执行cout<<”That is end”<<endl,最后程序结束。
结果(四)
解释:代码执行到r=resolution(a,b,c)时,调用函数Res resolution(a,b,c),执行到函数中的try语句块,由于a=1,b=-3不满足a==0&&b!=0条件,跳过if语句块的内容,又判断输入的a,b,c不满足b*b-4*a*c<0,跳过throw -1语句,向下执行到tmpr.x1=quotient(-b+sqrt(b*b-4*a*c),2*a)和语句tmpr.x2=quotient(-b-sqrt(b*b-4*a*c),2*a),调用函数float quotient(int a,int b)thorw(char*),判断b==0条件不符合,执行语句return a/(float)b,得到tmpr.x1=2,tmpr.x2=1返回tmpr,把tmpr赋值给r,最后输出结果x1=2,x2=1。
3、功能:二进制文件与文本文件比较
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
const char* name[3] = { "Antony","John","Tom" };
float score[3] = { 85,90,60 };
fstream txtfile, binfile; //建立文件流对象
txtfile.open("d:\\c++book\\record.txt", ios::out | ios::trunc);
binfile.open("d:\\c++book\\record.dat", ios::binary | ios::out | ios::trunc);
if (!txtfile) //判断文件是否创建或者打开成功,不成功则在屏幕上显示出cerr的文字段
{
cerr << "record.txt open or create error!" << endl;
exit(1);
}
if (!binfile) //判断文件是否创建或者打开成功,不成功则在屏幕上显示出cerr的文字段
{
cerr << "record.dat open or create error!" << endl;
exit(1);
}
for (int i = 0; i < 3; i++)
{
txtfile << name[i] << '\t' << score[i] << endl; //以文本文件的格式输出内容到文本文件中
binfile.write(name[i], 8 * sizeof(char)); //以二进制文件格式输出内容到record.dat文件中
binfile.write((char*)&score[i], sizeof(float));
}
txtfile.close();
binfile.close();
return 0;
}