钜形不锈钢水箱 发表于 2024-11-17 12:58:42

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]
查看完整版本: C++[非常与IO]