• C++ 基础与深度分析 Chapter7 深入I/O(文件与内存操作、流的状态、流的定位、流的同步)


    文件与内存操作

    文件

    在这里插入图片描述

    cin和cout是与终端的交互。cpp的I\O流,还能对文件和内存进行操作。
    文件操作主要使用了3个类模版:basic_ifstream输入, basic_ofstream输出, basic_fstream打开一个文件,同时接受输入和输出2种操作。
    在这里插入图片描述

    #include <iostream>
    #include <iomanip>
    #include <fstream>
    using namespace std;
    
    
    int main()
    {
        std::ofstream outFile("Myfile");
        outFile << "Jammy & Kin !\n";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    using namespace std;
    
    
    int main()
    {
        std::ofstream outFile;
        cout << outFile.is_open() << endl; // 0
        outFile.open("Myfile");
        cout << outFile.is_open() << endl; // 1
        outFile.close();
        cout << outFile.is_open() << endl; // 0
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    using namespace std;
    
    
    int main()
    {
        std::ofstream outFile;
        cout << outFile.is_open() << endl; // 0
        outFile.open("Myfile");
        outFile << "Jammy!\n"; // 系统已开始不写到文件里,而是写到缓存里
        outFile.close(); // close时,系统将缓存的内容放到文件里
        // 如果没有close,系统会根据机制,自动关闭。我们一般构造一个语句体(域),让它自动销毁
    
    
        std::ifstream inFile("Myfile"); // 文件名称
        std::string x;
        inFile >> x; // 等待x的输入
        cout << x << endl; // 将x的内容打到终端里 
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    通常in和out打开文件,光标都是在最开头。ate就是让光标放在最后。
    ate和app不一样的地方是,ate开始在文件末尾,可以移动到文件当中某一个位置。app只能放在文件的末尾,不同移到中间。
    trunc: 打开文件是用来写的,并且把文件之前的内容删除掉。
    binary: 能禁止系统特定的转换。
    在这里插入图片描述

    #include <iostream>
    #include <iomanip>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        // 把文件之前的内容删除,添加新的内容
        std::ofstream outFile("Myfile", std::ios_base::out | std::ios_base::trunc);
        outFile << "Hello World";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    内存

    在这里插入图片描述
    basic_istringsteam: 读取数据
    basic_ostringstream: 写入数据
    basic_stringstream: 读写
    在这里插入图片描述

    #include <iostream>
    #include <sstream>
    using namespace std;
    
    int main()
    {
        std::ostringstream obj1;
        obj1 << 1234; // obj1内存流对象,把1234整数写入,将整数转成了字符串
        auto res = obj1.str(); // res获取底层对应的内存,res类型是std::string
        cout << res << endl; // 1234,注意这里已经不是上面的1234整数了,而是一个字符串
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #include <iostream>
    #include <sstream>
    using namespace std;
    
    int main()
    {
        std::ostringstream obj1;
        obj1 << 10; 
        std::string res = obj1.str();
        std::istringstream obj2(res); //构造输入流,把读取的res内存读出来
        int x;
        obj2 >> x;
        cout << x << endl; // 10 obj2从res读取1和0,在内部完成解析,将1和0解析,然后存在int x中,输出
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    内存流也会受到打开流的影响,但是没有trunc和binary。

    int main()
    {
        std::ostringstream buf2("test", std::ios_base::ate);
        buf2 << 1;
        cout << buf2.str() << endl; // test1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    int main()
    {
        std::ostringstream buf2("test"); // ate去掉
        buf2 << 1;
        cout << buf2.str() << endl; // 1est
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    int main()
    {
        std::ostringstream buf2("test", std::ios_base::app);
        buf2 << 1;
        cout << buf2.str() << endl; // test1 str返回是cpp类型的字符串
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    在这里插入图片描述
    基于字符串流的字符串拼接优化

    #include <iostream>
    #include <sstream>
    using namespace std;
    
    int main()
    {
        std::string x;
        x += "Hello";
        x += " world";
        x += " Jammy";
        x += " Kin";
        // 这样性能比较差,先看string是否有足够的缓冲区足够保存新的字符串。
        // 将原有的stirng拷贝新的缓冲区,加上新的string,再把原缓冲区释放
        // 内存的不断地开辟和释放,非常耗时
        cout << x << endl; 
    
        // 等价于下面的代码
        std::ostringstream obj;
        obj << "Hello";
        obj << " world";
        obj << " Jammy";
        obj << " Kin";
        cout << obj.str() << endl; // 基于字符串流的字符串拼接优化,缓存满了,一次性刷新
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    流的状态

    在这里插入图片描述
    流的状态:正常状态,还是异常的状态。
    刚开始使用流,都是正常的,但是随着插入或者提取,可能会失败,就是异常的状态。
    在这里插入图片描述
    badbit

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        std::ofstream outFile;
        outFile << 10; // 流的异常状态,会产生badbit(不可恢复的流错误)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输入流的failbit

    int main()
    {
        int x;
        cin >> x; // 如果输入“Hello”,这样读取就失败了,cin就是failbit
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    输出流的failbit

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        std::ofstream outFile;
        outFile.close(); //这里outFile本身没有关联任何文件,是关闭状态,调用close再关闭,就会产生failbit。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    failbit是一种可以恢复的错误,不同于badbit。
    eofbit:(end of file)文件末尾,无法再读取。对于内存流和终端流都是有效的。

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        int x;
        cin >> x; // 1
        cout << std::cin.good() // 1
             << std::cin.bad() // 0
             << std::cin.fail() // 0
             << std::cin.eof() // 0
             << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        int x;
        cin >> x; // abc
        cout << std::cin.good() // 0
             << std::cin.bad() // 0
             << std::cin.fail() // 1
             << std::cin.eof() // 0
             << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    在这里插入图片描述
    通常,我们不给流设置复位。clear和setstate。
    在这里插入图片描述

    流的定位

    在这里插入图片描述
    流是一长串,那么往哪里进行写入和读取,这就需要流的定位。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    seekg()和seekp(),都是覆盖操作,而不是插入操作。
    在这里插入图片描述
    seekg有2个方法。重载了。
    在这里插入图片描述
    在这里插入图片描述

    流的同步

    在这里插入图片描述
    flush,将缓冲区内容扔到外部设备里,将缓冲区内容清空。
    在这里插入图片描述

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        cout << "What's your name \n"; // 如果这句话没占满缓冲区,下面等待用户输入,就在缓冲区里放着
        // 我们希望在等待用户输入之前,就把句子打出来
        // std::endl和std::flush 都可以
        cout.flush();
        std::string name;
        cin >> name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    sync可以选择清空缓冲区或者重新填充它。具体做哪个,库函数自己决定的。
    在这里插入图片描述
    unitbuf,单位缓冲区。本质含义是写入要大于等于1个字符,也就是只要写一个东西,就从缓冲区放到终端里。因为缓冲区太小了,就1个字符。好处是信息立即存入终端,坏处是效率的降低。
    在这里插入图片描述
    2个流(输入/输出)绑定到1个输出流。既可以多对一,但是不能一对多。A不可以既绑定输出流C,又绑定输出流D。
    在这里插入图片描述
    c++和c语言输入和输出函数同步,这样的同步一定是有成本的,效率一定是降低的。可以通过sync_with_stdio关闭。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    因为解除了同步。

  • 相关阅读:
    学生管理系统JAVA
    第六十二周周报
    Oracle 11G 支持自增主键方法
    计算机毕业设计Java计算机实验课程学习系统(源码+系统+mysql数据库+lw文档)
    SA实战 ·《SpringCloud Alibaba实战》第11章-服务容错加餐:Sentinel核心技术与配置规则(最全使用教程)
    哪里有期货开户的正规途径?
    【可视化大屏设计学习1】正式开始建设可视化平台了,学习路径写下来!大家一起沟通呀!~
    解决虚拟机磁盘满了,无法上传文件,给虚拟机扩容问题
    springcloud五大组件:Eureka:注册中心、Zuul:服务网关、Ribbon:负载均衡、Feign:服务调用、Hystix:熔断器
    Go学习笔记 -- 并发原理
  • 原文地址:https://blog.csdn.net/weixin_43716712/article/details/125393076