C++[非常与IO]
2023-3-17首次编辑Unit 10:非常
一.概念
[*]非常处理就是处理步伐中的错误
[*]错误是指在步伐运行的过程中发生的一些非常事故
二.作用
办理C语言处理非常的方法缺陷:
[*]返回值意思不明确
[*]返回值只能返回一条信息
[*]返回值可以忽略
三.根本语法与执行流程
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
int func(int a, int b)
{
if (b==0)
{
//第二步:抛出异常
throw 10; //抛出一个int类型的异常
cout << "throw后的代码" << endl;
}
}
void test()
{
int a = 10;
int b = 0;
//第一步:把有可能出现异常的代码块放到try中
try
{
func(a, b);
cout << "func后的代码" << endl;
}
//第三步:接受一个int类型的异常
catch (int)
{
cout << "接收到一个int类型的异常" << endl;
}
}
int main()
{
test();
system("pause");
return 0;
}
四.非常的上风
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
class Maker
{
public:
void printMaker()
{
cout << "除数不能为0" << endl;
}
};
int func(int a, int b)
{
if (b == 0)
{
//Maker m;
//throw m; //抛出一个Maker类型的异常
throw 20.22; //抛出一个double类型的异常
}
return a / b;
}
void test()
{
int a = 10;
int b = 0;
try
{
func(a, b);
}
catch (int)
{
cout << "接收到一个int类型的异常" << endl;
}
catch (Maker maker)
{
cout << "接收到一个Maker类型的异常" << endl;
maker.printMaker();
}
catch (double)
{
//如果不想处理异常,可以往上抛出,抛给调用本函数的函数
throw;
}
}
int main()
{
try
{
test();
}
catch (double)
{
cout << "接收一个double类型的异常" << endl;
}
system("pause");
return 0;
}
[*]用户可以忽略返回值,但不能忽略非常,假如忽略将会报错
[*]返回值只能返回一条信息,但对象有成员函数,可以包含多个信息
[*]可以逐层依赖处理非常
五.非常的严格类型匹配
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
class Maker
{
public:
};
int func(int a, int b)
{
if (b == 0)
{
//Maker m;
//throw m; //抛出一个Maker类型的异常
//throw 20.22; //抛出一个double类型的异常
//throw 'c'; //抛出一个char类型的异常
throw 20.0f; //抛出一个float类型的异常
}
}
void test()
{
int a = 10;
int b = 0;
try
{
func(a, b);
}
catch (Maker)
{
cout << "接受一个Maker类型的异常" << endl;
}
catch (double)
{
cout << "接受一个double类型的异常" << endl;
}
catch (char)
{
cout << "接受一个char类型的异常" << endl;
}
catch (...) //接受其他类型的异常
{
cout << "接受一个其他类型的异常" << endl;
}
}
int main()
{
test();
system("pause");
return 0;
}
六.非常的接口声明
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
void func() throw(int, char) //只允许抛出int或者char异常
{
throw 10; //抛出一个double类型的异常,Qt上程序会阻挡
}
int main()
{
try
{
func();
}
catch (int)
{
cout << "int" << endl;
}
catch (...)
{
cout << "..." << endl;
}
system("pause");
return 0;
}
七.栈解旋
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
class Maker
{
public:
Maker()
{
cout << "Maker的构造" << endl;
}
Maker(const Maker &m)
{
cout << "Maker的拷贝构造" << endl;
}
~Maker()
{
cout << "Maker的析构" << endl;
}
};
void func()
{
//栈解旋:
//在抛出异常的函数中,如果抛出异常之后,但函数没有结束,此时栈上申请的对象都会被释放
Maker m;
throw m; //这个m是Maker m拷贝的一份
cout << "func函数结束" << endl;
}
void test()
{
try
{
func();
cout << "func代码后" << endl;
}
catch (Maker)
{
cout << "接收一个Maker类型的异常" << endl;
}
}
int main()
{
test();
system("pause");
return 0;
}
八.非常变量的生命周期
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
class Maker
{
public:
Maker()
{
cout << "Maker的构造" << endl;
}
Maker(const Maker &m)
{
cout << "Maker的拷贝构造" << endl;
}
~Maker()
{
cout << "Maker的析构" << endl;
}
};
//产生三个对象
void func1()
{
Maker m; //第一个对象,在异常接收前被释放
throw m; //第二个对象,是第一个对象拷贝过来的
}
void test1()
{
try
{
func1();
}
catch (Maker m1) //第三个对象,是第二个对象拷贝过来的
{
cout << "接收一个Maker类型的异常" << endl;
//第二个对象和第三个对象在catch结束时释放
}
}
//产生两个对象
void func2()
{
throw Maker(); //第一个对象,匿名对象
}
void test2()
{
try
{
func2();
}
catch (Maker m1) //第二个对象,是第一个对象拷贝过来的
{
cout << "接收一个Maker类型的异常" << endl;
//第一个对象和第二个对象在catch结束时释放
}
}
//产生一个对象(常用)
void func3()
{
throw Maker(); //匿名对象
}
void test3()
{
try
{
func3();
}
catch (Maker &m1) //引用匿名对象
{
cout << "接收一个Maker类型的异常" << endl;
}
}
//注意:
void func4()
{
//编译器不允许对栈中的匿名对象取地址操作
//throw Maker(); //err
//编译器允许对堆区中的匿名对象取地址操作
throw new Maker();
}
void test4()
{
try
{
func4();
}
catch (Maker* m1) //对匿名对象取地址
{
cout << "接收一个Maker类型的异常" << endl;
delete m1;
}
}
int main()
{
test1();
test2();
test3();
test4();
system("pause");
return 0;
}
九.非常的多态
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
//异常的基类
class Father
{
public:
virtual void printM()
{
}
};
//1.有继承
class SonNULL :public Father
{
public:
virtual void printM() //2.重写父类的虚函数
{
cout << "空指针异常" << endl;
}
};
class SonOut :public Father
{
public:
virtual void printM()
{
cout << "越位溢出" << endl;
}
};
void func(int a, int b)
{
if (a==0)
{
throw SonNULL();
}
if (b==0)
{
throw SonOut();
}
}
void test()
{
int a = 0;
int b = 10;
try
{
func(a, b);
}
catch (Father &f) //3.父类引用指向子类对象
{
f.printM();
}
}
int main()
{
test();
system("pause");
return 0;
}
十.体系提供的尺度非常
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
#include <string>
#include <stdexcept> //标准异常库(Vs2013可以不需要写)
using namespace std;
//1.系统的标准异常类
class Maker1
{
public:
Maker1(int age)
{
if (age<0||age>150)
{
throw out_of_range("系统的标准异常类:年龄不在范围内");
}
else
{
this->age = age;
}
}
public:
int age;
};
void test1()
{
try
{
Maker1 m(200);
}
catch (out_of_range &ex)
{
cout << ex.what() << endl;
}
}
//2.自己编写的异常类
class MyOut_of :public exception
{
public:
MyOut_of(const char* errorinfo)
{
//const char*转换string
this->m_Info = string(errorinfo);
}
MyOut_of(const string errorinfo)
{
this->m_Info = errorinfo;
}
const char* what() const
{
//把string转换成const char*
return this->m_Info.c_str();
}
public:
string m_Info;
};
class Maker2
{
public:
Maker2(int age)
{
if (age<0 || age>150)
{
throw MyOut_of("自己编写的异常类:年龄不在范围内");
}
else
{
this->age = age;
}
}
public:
int age;
};
void test2()
{
try
{
Maker2(200);
}
catch (MyOut_of &ex)
{
cout << ex.what() << endl;
}
}
int main()
{
test1();
test2();
system("pause");
return 0;
}
Unit 11:IO
流的概念和堕泪库的结构
[*]尺度IO:对体系的尺度输入输出装备进行读写
[*]文件IO:对磁盘进行输入输出读写
[*]串IO:对内存进行读写
一.体系尺度的输入流
成员函数:
[*]cin.get() //一次只能读取一个字符
[*]cin.get(一个参数) //读取一个字符
[*]cin.get(两个参数) //可以读取字符串
[*]cin.getline() //取一行,换行符丢弃
[*]cin.ignore() //忽略
[*]cin.peek() //偷窥
[*]cin.putback() //放回
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
//单个输入
void test1()
{
//输入ab
char c = cin.get(); //读取a
cout << c << endl;
c = cin.get(); //读取b
cout << c << endl;
c = cin.get(); //读取换行符
cout << c << endl;
//其他形式
cin.get(c); //阻塞
cout << c << endl;
cin.get(c); //读取换行符
cout << c << endl;
char ch1, ch2, ch3, ch4;
cin.get(ch1).get(ch2).get(ch3).get(ch4);
cout << ch1 << ch2 << ch3 << ch4 << endl;
}
//按行输入
void test2()
{
char buf = { 0 };
cin.get(buf, 1024); //读取缓冲区时,换行符不拿走
char c = cin.get();
if (c=='\n')
{
cout << "换行符还在缓冲区中" << endl;
}
cout << buf << endl;
cin.getline(buf, 1024); //读取缓冲区时,换行符丢弃
char ch = cin.get(); //阻塞
if (ch == '/n')
{
cout << "换行符还在缓冲区中" << endl;
}
cout << buf << endl;
}
//忽略(参数为N,表示忽略N个字符)
void test3()
{
输入ab
//cin.ignore(); //默认忽略缓冲区内第一个字符
//char c = cin.get(); //b
//cout << c << endl;
//输入abcde
cin.ignore(3); //忽略缓冲区内前三个字符
char ch = cin.get(); //d
cout << ch<< endl;
}
//偷窥(只看不拿)
void test4()
{
//输入a
char c = cin.peek(); //偷窥第一个字符a
cout << "c:" << c << endl;
char ch = cin.get(); //拿走a
cout << "ch:" << ch << endl;
}
//返回(拿走后,放回去)
void test5()
{
//输入a
char c = cin.get(); //拿走a
cout << c << endl;
cin.putback(c); //放回a
char buf = { 0 };
cin.getline(buf, 1024); //拿走放回的a
cout << buf << endl;
}
//综合案例一:判断用户输入的是字符串还是数字
void test6()
{
cout << "请输入一个字符串或数字:" << endl;
char c = cin.peek();
if (c >= '0' && c <= '9')
{
int num;
cin >> num;
cout << "输入的数字是:" << num << endl;
}
else
{
char buf = { 0 };
cin >> buf;
cout << "输入的字符串是:" << buf << endl;
}
}
//综合案例二:输入0~10的数字,直到输入正确为止
void test7()
{
int num;
while (1)
{
cin >> num;
if (num >= 0 && num <= 10)
{
cout << "输入正确!!!" << endl;
break;
}
cout << "重新输入:" << endl;
//重置标志位
cin.clear();
//拿走缓冲区内容
char buf = { 0 };
cin.getline(buf, 1024);
//打印标志位
//0表示正常,无数据
//1表示不正常,有数据
cout << cin.fail() << endl;
}
}
int main()
{
//test1();
//test2();
//test3();
//test4();
//test5();
//test6();
test7();
system("pause");
return 0;
}
二.体系尺度的输出流
https://i-blog.csdnimg.cn/blog_migrate/e2a1578957435349e5a4cd6052c2cde9.png
https://i-blog.csdnimg.cn/blog_migrate/e3801228cf5c65ac204b08be2af56263.png
https://i-blog.csdnimg.cn/blog_migrate/8907aa9c28a379957939b9dc7f7870dd.png
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
//单个输出
void test1()
{
cout.put('c');
//链式编程
cout.put('a').put('b').put('c');
}
//按行输出
void test2()
{
char buf[] = "Hello World";
cout.write(buf, strlen(buf));
}
//通过流成员函数实现格式化的输出
void test3()
{
int num = 99;
//设置宽度
cout.width(20);
//填充
cout.fill('*');
//让数据在左边
cout.setf(ios::left);
//卸载十进制
cout.unsetf(ios::dec);
//安装十六进制
cout.setf(ios::hex);
//显示基数
cout.setf(ios::showbase);
//卸载十六进制
cout.unsetf(ios::hex);
//安装八进制
cout.setf(ios::oct);
cout << num << endl;
}
//通过控制符格式化输出(引入头文件iomanip)
#include <iomanip>
void test4()
{
int num = 99;
//设置宽度
cout << setw(20);
//填充
cout << setfill('~');
//显示基数
cout << setiosflags(ios::showbase);
//让数据在左边
cout << setiosflags(ios::left);
//十六进制
cout << hex;
//八进制
cout << oct;
//十进制
cout << dec;
cout << num << endl;
}
//打印浮点数后面的小数点
void test5()
{
double d = 20.22;
//设置显示浮点数
cout << setiosflags(ios::fixed);
//显示小数点后10位
cout << setprecision(10) << endl;
cout << d << endl;
}
int main()
{
//test1();
//test2();
//test3();
//test4();
test5();
system("pause");
return 0;
}
三.文件读写操作
https://i-blog.csdnimg.cn/blog_migrate/d00c8f4a93686e0a624f40ae565a610d.png
C++文件读写:
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;
//1.引入头文件
#include <fstream>
//把程序中的信息输出到缓冲区,然后写到文件(写文件)
void test1()
{
//2.定义流对象
ofstream ofs;
//3.打开文件,以写的方式打开(如果没有文件,就创建)
ofs.open("test.txt", ios::out | ios::trunc);
//4.判断是否打开成功
if (!ofs.is_open())
{
cout << "打开文件" << endl;
}
//5.写信息
ofs << "姓名:悟空" << endl;
ofs << "年龄:18" << endl;
ofs << "身高:180cm" << endl;
//6.关闭文件
ofs.close(); //关闭文件,并刷新缓冲区
}
//把磁盘信息输入到缓冲区,然后读到程序中(读文件)
void test2()
{
ifstream ifs;
ifs.open("test.txt", ios::in);
if (ifs.is_open()==false)
{
cout << "打开失败" << endl;
}
//第一种方式读取文件
//一行一行读取
/*char buf = { 0 };
while (ifs >> buf)
{
cout << buf << endl;
}*/
//第二种方式读文件
/*char buf = { 0 };
while (!ifs.eof()) //判断是否读到文件尾部
{
ifs.getline(buf, sizeof(buf));
cout << buf << endl;
}*/
//第三种方式读取文件
//单个字符读取
char c;
while ((c=ifs.get())!=EOF)
{
cout << c;
}
ifs.close();
}
int main()
{
//test1();
test2();
system("pause");
return 0;
}
四.二进制文件读写
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
class Maker
{
public:
Maker()
{
}
Maker(const char* name, int age)
{
this->age = age;
strcpy(this->name, name);
}
public:
char name;
int age;
};
//写文件
void test1()
{
Maker m1("悟空", 18);
Maker m2("贝吉塔", 22);
ofstream ofs;
ofs.open("test.txt", ios::out | ios::trunc | ios::binary);
if (!ofs.is_open())
{
cout << "打开失败" << endl;
}
//写
ofs.write((const char *)&m1, sizeof(Maker));
ofs.write((const char *)&m2, sizeof(Maker));
ofs.close();
}
//读文件
void test2()
{
ifstream ifs;
ifs.open("test.txt", ios::in | ios::binary);
if (!ifs.is_open())
{
cout << "打开失败" << endl;
}
//读
Maker m1;
Maker m2;
ifs.read((char*)&m1, sizeof(Maker));
ifs.read((char*)&m2, sizeof(Maker));
cout << "Name:" << m1.name << " Age:" << m1.age << endl;
cout << "Name:" << m2.name << " Age:" << m2.age << endl;
ifs.close();
}
//注意:当文件读写时,类中的成员变量不要有string类型
class Maker2
{
public:
Maker2()
{
}
Maker2(string name, int age)
{
this->name = name;
this->age = age;
}
public:
string name;
//string类中有一个成员指针char*,该指针指向存储字符串的空间
//当我们把string类的数据存储到文件中,再读出来时,不能保证指针有效
//string 开辟的空间如果大于16个字节就在堆区,小于就在栈区
int age;
};
int main()
{
test1();
test2();
system("pause");
return 0;
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]