C++中异常与文件操作(包括输入输出流)

7 篇文章 0 订阅

关于异常的概念:
一种程序控制机制,与函数机制独立互补。
设计的目的:
异常是冲着改变程序控制结构,以适应面对对象的程序而有效的工作。
关于异常的概念的部分代码:
#include

using namespace std;

int DDiv(int x, int y)
{
if (0 == y)
{
throw 0;
}

return x / y;

}

int Div(int x, int y)
{
/if (y == 0)
{
throw 0; //抛出一个整型
}
return x / y;
/

int ret = DDiv(x, y);  //异常跨越函数,可以继续向上抛出异常

return ret;

}

int main()
{
int a, b;
cin >> a >> b;

try
{
	cout << Div(a, b) << endl;
}
catch (int)
{	
	cout << "被除数是0" << endl;
}
catch (char)
{
	cout << "xxxxx" << endl;
}

return 0;

}
异常的语法:
1.若有异常,则通过throw操作创造一个异常对象并抛掷。
2.将可能出现的异常快嵌在try语句中,然后执行try语句保护段。
3.如果在try保护段没有发生异常,那么catch子句就不执行。程序从try快后跟随最后一个catch子句后面的语句继续执行下去。
4.catch子句跟在try后出现的顺序被检查。匹配的catch子句将捕获并处理异常。
5.如果匹配的处理器未找到,则运行函数terminate将被自动调用,
6处理不了的异常可以在catch的最后一个分支,使用throw语法往上扔。
7.异常机制与函数机制互不干涉。捕捉的方式就是基本类型的匹配。
8。异常捕捉严格按照类型匹配。

栈解旋的概念:异常被抛出后,从进入try快起,到异常被抛掷前,这期间在栈上的所有构造对象,都会被自动析构,析构的顺序与构造的顺序相反,这一过程称为栈的解旋。
栈解旋:
#include

using namespace std;

class Test
{
public:
Test()
{
cout << “Test构造函数” << endl;
}

~Test()
{
	cout << "Test析构函数" << endl;
}

};

int Div(int x, int y)
{
if (0 == y)
{
throw 0; //一旦程序抛出异常, 从进入try起,到throw语句,栈上所有对象都被析构
}

return x / y;

}

int main()
{
int a, b;
cin >> a >> b;

try
{
	Test t;
	cout << Div(a, b) << endl;
	cout << "12345" << endl;
}
catch(int)
{
	cout << "zero exception" << endl;
}

cout << "helloworld" << endl;

return 0;

异常接口声明:

1.为了加强程序可读性,可以在函数声明中列出可能抛出的所有异常类型。
2.如果在函数声明中没有包含任何接口声明,则次函数可以抛掷任何类型的异常。如void func();
3.一个不抛掷任何类型异常的函数可以声明为:
void func() throw();
4.如果一个函数抛出了它的异常接口声明所不允许抛出的异常,unexpected函数会被调用,该函数默认行为调用terminate函数中止程序。
#include

using namespace std;

//int Div(int x, int y); //函数Div可以抛出任意类型的异常
int Div(int x, int y) throw (int, char); //函数Div只能抛出int类型的异常
//int Div(int x, int y) throw(); //函数Div不会抛出异常

int main()
{
int a, b;
cin >> a >> b;

try
{
	cout << Div(a, b) << endl;
}
catch (int)
{	
	cout << "被除数是0" << endl;
}
catch (char)
{
	cout << "xxxxx" << endl;
}

return 0;

}

int Div(int x, int y) throw(int)
{
if (y == 0)
{
//throw 1.11; //抛出一个整型
throw 0;
}
return x / y;
}

异常的应用:
异常的层次结构:
1.异常是类-创造自己的异常类
2.异常派生
3.异常中的数据:数据成员
4.按引用传递异常
5.在异常中使用虚函数。
#include

using namespace std;

class array
{
private:
int length;
int *data;
public:
class eSize //内部类 抽象父类
{
protected:
const char *ErrMsg;
public:
eSize(const char *e)
{
ErrMsg = e;
}
virtual void printErr() = 0;
};

class eNegative : public eSize
{
public:
	eNegative() : eSize("eNegative exception")
	{
		
	}
	void printErr()
	{
		cout << ErrMsg << endl;
	}
};

class eZero : public eSize
{
public:
	eZero() : eSize("eZero exception")
	{
		
	}
	void printErr()
	{
		cout << ErrMsg << endl;
	}
	
};

class eTooSmall : public eSize
{
public:
	eTooSmall() : eSize("eTooSmall exception")
	{
		
	}
	void printErr()
	{
		cout << ErrMsg << endl;
	}
	
};

class eTooBig : public eSize
{
public:
	eTooBig() : eSize("eTooBig exception")
	{
		
	}
	void printErr()
	{
		cout << ErrMsg << endl;
	}
	
};

array(int l)
{
	if (l < 0)
	{
		throw new eNegative;
	}
	else if (l == 0)
	{
		throw new eZero;
	}
	else if (l > 1000)
	{
		throw new eTooBig;
	}
	else if (l < 10)
	{
		throw new eTooSmall;
	}

	length = l;
	data = new int[length];
}

};

int main()
{
try{
array a(10000);
}
catch(array::eSize *e)
{
e->printErr();
}

return 0;

}

输入输出流:部分操作
输入:
与iostream类库有关的头文件
iostream:包含了对输入输出流的进行操作的基本信息。
fstream:用于用户管理的I/O操作。
strstream:用于字符串流I/O。
stdiostream:用于混合使用C和C++的I/O机制。
iomanip:在使用格式化I/O时应该包含此文件。
在iostream中头文件中定义的流对象:
在iostream中头文件中定义的类有:ios,istream,ostream,iostream,istream_withassign,ostream_withassign,等
同时定义了4中流对象:cin,cout,cerr,clog。
标准输入流:
对象cin:
重点掌握的函数:
cin.get() //一次只能读取一个字符, 遇到EOF结束。
cin.get(一个参数) //读一个字符
cin.get(三个参数) //可以读字符串
cin.getline()
cin.ignore()
cin.peek()
cin.putback()

#include //输入(cin的一些操作)

using namespace std;

int main()
{
char ch;
char str[64] = {0};
int i = 0;

/*ch = cin.get();   //获取一个字符
cout << ch << endl;

while ((ch = cin.get()) != '\n')
{
	str[i++] = ch;
}
cout << str << endl;*/

/*cin.get(ch);
cout << ch << endl;*/

/*cin.get(str, 8);  //从标准输入获取8个字符放在str数组中
cout << str << endl;*/

/*cin.getline(str, 32);   //获取一行数据,最多32个字节
cout << str << endl;*/

/*cin.ignore(5);   //忽略前五个字节
cin >> str;
cout << str << endl;*/

/*ch = cin.peek();   //从标准输入读取一个字节,并且不清空标准输入
cout << ch << endl;

cin >> str;
cout << str << endl;*/

cin >> ch;
cout << ch << endl;

cin.putback(ch);    //把ch写回标准输入
cin >> str;
cout << str << endl;


return 0;

}

输出:
标准输出流:
标准输出流对象cout
cout.flush()
cout.put()
cout.write()
cout.width()
cout.fill()
cout.setf()
manipulator(操作符,控制符)
fiush
endl
oct
dec
hex
setbase
setw
setfill
setprecision

#include
#include

using namespace std;

int main()
{
#if 0
//控制符方法控制输出格式
int a = 1000;
cout << a << endl;
cout << oct << a << endl; //8进制输出
cout << dec << a << endl; //10进制输出
cout << hex << a << endl; //16进制输出

char *str = "helloworld";
cout << setw(20) << str << endl;
cout << setfill('*') << setw(20) << str << endl;

double p = 222.00000 / 7.0000;
cout << p << endl;
cout << setprecision(3) << p << endl;   //保留3位数字
cout << setiosflags(ios::scientific) << p << endl;   //指数形式输出

#endif

//使用成员函数的方法
int a = 1000;
int b = 2000;
cout.unsetf(ios::dec);    //先结束十进制输出
cout.setf(ios::oct);      //再开始八进制输出
cout << a << endl;
cout.unsetf(ios::oct);
cout.setf(ios::hex);
cout << a << endl;
cout << b << endl;

char *str = "helloworld";
cout.width(20);
cout.setf(ios::left);
cout.fill('*');
cout << str << endl;

double p = 2222.00000 / 7.0000;
cout.precision(4);
cout << p << endl;
cout.setf(ios::scientific);
cout << p << endl;
cout.setf(ios::fixed);
cout << p << endl;
return 0;

}
文件操作:
#include
//#include //文件输入
//#include //文件输出
#include

using namespace std;

int main()
{
/ofstream ofs; //文件输出对象
if (!ofs.open(“hello.txt”))
{
cout << “打开失败” << endl;
}
/

char *buf = "helloworld";
ofstream ofs("hello.txt");
ofs << buf;
ofs.close();

char str[32] = {0};
ifstream ifs("hello.txt");
ifs >> str;
cout << str << endl;

return 0;

}

const_cast.cpp:
#include

using namespace std;

int main()
{
const int a = 100;
int *p = const_cast<int *>(&a); //去除变量的const属性

int &k = const_cast<int &>(a);

//int &b = 1;  //用常量初始化普通引用  错误
const int &c = 1;  //用常量初始化常引用 

return 0;

}

dynamic_cast.cpp:
#include

using namespace std;

int main()
{
const int a = 100;
int *p = const_cast<int *>(&a); //去除变量的const属性

int &k = const_cast<int &>(a);

//int &b = 1;  //用常量初始化普通引用  错误
const int &c = 1;  //用常量初始化常引用 

return 0;

}

reinterprint.cpp;
#include

using namespace std;

int main()
{
int *a;
double b = 1.11;

a = reinterpret_cast<int *>(&b);  //用于普通类型指针之间的转换,不安全

a = reinterpret_cast<int *>(0x100);   //用于整数和指针之间的转换

return 0;

}

static_cast.cpp:
#include

using namespace std;

class Parent
{
private:
int a;
};

class Child : public Parent
{
private:
int b;
};

int main()
{
int a = 10;
float b = 1.11;
int *p;

a = static_cast<int>(b);  //用于基本类型之间的转换

//p = static_cast<int *>(&b);   //不能用于基本类型指针之间的转换

Parent par;
Child ch;

par = static_cast<Parent>(ch);   //用于有继承关系的类之间的转换

Parent *p1 = static_cast<Parent *>(new Child);  //用于有继承关系的类指针之间的转换

return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值