QtC++ 技术分析3 - IOStream

目录

    • iostream
      • scanf/printf
      • iostream 整体架构
        • 流相关类
        • 流缓冲区
      • 模板特化后整体结构
      • 文件流
        • 文件流对象创建
        • 常见文件流操作
        • 输出格式设定
        • 文件流状态
      • 字符串流
        • 字符串流内部缓冲区
        • 字符串流使用
      • 流缓冲区
      • 用户自定义 IO

iostream


scanf/printf

几种常见的输入输出流函数

  • scanf 从键盘接收输入数据
  • printf 向屏幕输出数据
  • fscanf 从文件输入数据
  • fprintf 向文件输出数据
  • sscanf 从内存块读取数据
  • sprintf 向内存块输出数据。

C 语言输入输出方法存在这些缺点:
无法在编译阶段检查 scanf/printf 函数组参数的错误;无法对 scanf/printf 函数组的接口进行扩展以处理新的数据类型;scanf/printf 函数组的执行速度慢;scanf/printf 函数组所占用的空间无法被优化。


iostream 整体架构

iostream 包括以下三个层次
在这里插入图片描述

输入输出特性

  • 无论是输出还是输入操作,都经由一个缓冲区进行处理
  • 输出时,数据先写入到缓冲区,直到缓冲区满,其中的数据才会被真正写入到外部设备
  • 即便仅输入一个字符,也必须经过缓冲区

流相关类

iostream 整体架构图
在这里插入图片描述

charT 表示流中字符的类型
模板参数 traits 表示字符的特征
模板参数 allocator 表示堆管理器,该参数的默认值是系统的堆管理器


类模板 basic_ios 负责管理流缓冲区。它含有一个指针,指向流缓冲区。它还含有一个状态信息,来记录流缓冲区中数据的完备性。

类模板 basic_istream 以及 basic_ostream 分别负责数据的输入和输出
basic_iostream 通过继承这两个类模板,既能处理输入也能处理输出。

类模板 basic_istringstream 从一个类型为 basic_string 的字符串对象读取数据
类模板 basic_ostringstream 则向这种类型的字符串对象输出数据


流缓冲区

basic_ios 派生类中的缓冲区指针会指向 basic_streambuf 或者 basic_filebuf 的对象

抽象类型 basic_streambuf 不含有任何关于外部设备的信息

类模板 basic_filebuf 将输出缓冲区中的数据写入文件,或者将文件中的数据读取到输入缓冲区


模板特化后整体结构

iostream 将所有的 charT 特化为 char ,所有的 traits 特化为 char_traits< char>

iostream 还将所有的 charT 特化为 wchar_t,所有的 traits 特化为char_traits<wchar_t >


文件流

basic_ifstream 以及 basic_ofstream 分别负责文件的输入和输出
basic_fstream 能够对文件进行输入和输出双向的操作


文件流对象创建

fstream 代码实例:创建一个文件流对象 fs,在文件“test.txt”的尾部写入数据

ios_base 中定义了 6 个常量

  • in 表示读一个文件
  • out 表示写一个文件
  • app 表示仅在一个文件的末尾写入
  • trunc 表示清空文件内容
  • binary 表示以二进制方式访问一个文件
  • ate(是 at end 的缩写)表示初始的读/写位置为文件的末尾。
fstream fs("test.txt", ios_base::out | ios_base::app)

当读入文件(in 模式)则要求文件必须存在;
当写入文件(out 模式)指定文件可不存在,由系统新建一个;


常见文件流操作

一般的,你可以直接使用 << 或者 >> 执行输入输出操作
下面代码展示使用 fstream 对文件读写流程

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    // 打开文件,以输入、输出和追加的方式打开
    fstream fs("data\\test.txt", ios_base::in | ios_base::out | ios_base::app);

    // 检查文件是否成功打开,如果没有成功打开则输出错误信息并退出程序
    if (!fs) {
        cerr << "cannot open test.txt";
        exit(-1);
    }

    // 向文件中写入字符串 "hello, world\n"
    fs << "hello, world\n";

    // 将文件读写位置重新定位到文件开头
    fs.seekg(0);

    // 定义字符串变量 s,从文件中读取一个单词并存储到字符串 s 中
    string s;
    fs >> s;

    // 输出字符串 s
    cout << s;
}

常用 basic_istream 中的 getline()获取一整行的文本内容


输出格式设定

hex、oct、dec 分别将输出的数制设置为十六进制、八进制和默认的十进制
cout << hex << 20;

setw,流操作符,设置其后紧接着的那个数据的输出宽度
cout << swtw(4) << 3;

setprecision(m) 将设置小数点及其后面的数字占用 m 个字符的位置

boolalpha 流操作符,可以让 bool 类型数据输出形式为 true 何 false 而不是 1 和 0

left 流操作符,结果左对齐


文件流状态

C++流提供了以下的几个成员函数来返回一个流的状态信息

  1. eof()。如果输入流已经到达末尾,该函数返回真。
  2. bad()。如果用户试图对一个流对象执行非法操作,比如将文件指针移动到文件尾部之后的某个地方,该函数返回真,表示流对象被破坏了。
  3. fail()。如果施加到流的某个操作未能成功,比如一个输入流对象希望读取一个整数但是实际的输入数据却是一个字符串,该函数将返回真。
  4. good()。当以上条件都没有出现时,该函数返回真。

流使用者可以主动地分析流中的数据,调用成员函数 setstate()来设置流的状态信息

char ch;
if ((ch = ifs.get()) != '<' )
    is.setstate( ios_base::failbit );

字符串流

介绍类模板 basic_stringstream 读取和输出到一个 basic_string 对象的流程


字符串流内部缓冲区

stringstream 对象的流缓冲区指针指向一个 stringbuff 对象,该对象管理一个内部的字符缓冲区

内部字符缓冲区有两个指针:读取操作会后移“读指针”,而写入操作会后移“写指针”


字符串流使用

// istringstream使用
int i;
if (istringstream(argv[1]) >> i)

// ostringstream使用
struct date {
    int day,month,year;
} today = {9,3,2011};
ostringstream ostr;      ①
ostr << today.month << '-' << today.day <<'-' << today.year;if (ostr)
    cout<<ostr.str();

流缓冲区

可以令多个流对象共享一个流缓冲区

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    ofstream dec_stream( "demo.txt" );   ①
    ostream  hex_stream( dec_stream.rdbuf() );  ②
    hex_stream << hex << showbase;
    int a[4] = {12, 34, 56, 78};
    for (int i=1; i<4; i++){
            dec_stream << a[i];                        ③
            hex_stream << "[" << a[i] << "] ";}
    return 0;
}

流缓冲区可以执行复制操作

#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;

int main()
{
    // 打开红楼梦文本文件
    ifstream fs("hong_lou_meng.txt");

    // 将文件内容读取到stringstream对象中
    stringstream ss;
    ss << fs.rdbuf();   // ①

    // 将stringstream对象中的内容转为字符串类型
    string str = ss.str();      // ②

    // 查找字符串 "黛玉" 最后一次出现的位置
    string::size_type pos = str.rfind("黛玉");

    // 将stringstream对象的读写位置定位到 "黛玉" 最后一次出现的位置
    ss.seekg(pos);

    // 读取一行字符串,即 "黛玉" 最后一次出现的那句话
    string one_line;
    getline(ss, one_line);

    // 输出 "黛玉" 最后一次出现的那句话
    cout << one_line << endl;

    return 0;
}

用户自定义 IO

通过定义类,附加两个友元函数,并利用 ostreaminstream ,即可实现自定义 IO

#include <iostream> //包含输入输出流库
using namespace std; //使用标准命名空间

class CPoint { //定义CPoint类
public:
    CPoint(double p_x=0, double p_y=0) {x=p_x;  y=p_y;}; //构造函数
    friend ostream& operator << (ostream&, const CPoint&); //输出运算符重载函数的友元声明
    friend istream& operator >> (istream&, CPoint&); //输入运算符重载函数的友元声明
private:
    double x,y; //CPoint对象的x和y坐标
};

ostream& operator <<( ostream& os, const CPoint& point ) //输出运算符重载函数的实现
{
    os << "<" << point.x << "," << point.y << ">"; //输出CPoint对象的坐标
    return os; //返回输出流对象
}

istream& operator >>(istream& is, CPoint& point) //输入运算符重载函数的实现
{
    char ch;
    is >> ch;
    if ( ch!='<'){  //如果输入不是以 '<' 开始,则输入失败
            is.setstate( ios_base::failbit ); //设置输入流的状态为失败
            return is; //返回输入流对象
    }
    is >> point.x >> ch >> point.y >> ch; //输入CPoint对象的坐标
}

int main() //主函数
{
    CPoint p; //定义一个CPoint对象p
    while ( cin>> p ) //从标准输入流中读取CPoint对象,如果读取成功则进入循环
            cout << p << endl; //输出CPoint对象p,然后换行
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/51386.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

操作系统4

文件管理 文件的逻辑结构 文件的目录 文件的物理结构 文件存储空间管理 文件的基本操作

【深度学习】以图搜索- 2021sota repVgg来抽取向量 + facebook的faiss的做特征检索, 从环境搭建到运行案例从0到1

文章目录 前言安装小试牛刀用repVgg抽取向量构建Faiss索引进行相似性搜索项目延伸总结 前言 Faiss的全称是Facebook AI Similarity Search。 这是一个开源库&#xff0c;针对高维空间中的海量数据&#xff0c;提供了高效且可靠的检索方法。 暴力检索耗时巨大&#xff0c;对于…

Mac下certificate verify failed: unable to get local issuer certificate

出现这个问题&#xff0c;可以安装证书 在finder中查找 Install Certificates.command找到后双击&#xff0c;或者使用其他终端打开 安装完即可

tcp三次握手python实现和结果

下载抓包工具 安装 使用1 使用2 结果 红色笔为想要发送的数据。 代码 from scapy.all import * import logginglogging.getLogger(scapy.runtime).setLevel(logging.ERROR)target_ip = 172.20.211.4 target_port = 80 data = GET / HTTP/1.0 \r\n\r\ndef start_tcp(target_…

Mac代码编辑器sublime text 4中文注册版下载

Sublime Text 4 for Mac简单实用功能强大&#xff0c;是程序员敲代码必备的代码编辑器&#xff0c;sublime text 4中文注册版支持多种编程语言&#xff0c;包括C、Java、Python、Ruby等&#xff0c;可以帮助程序员快速编写代码。Sublime Text的界面简洁、美观&#xff0c;支持多…

上传图片到腾讯云对象存储桶cos 【腾讯云对象存储桶】【cos】【el-upload】【vue3】【上传头像】【删除】

1、首先登录腾讯云官网控制台 进入对象存储页面 2、找到跨越访问CIRS设置 配置规则 点击添加规则 填写信息 3、书写代码 这里用VUE3书写 第一种用按钮出发事件形式 <template><div><input type"file" change"handleFileChange" /><…

【设计模式】详解观察者模式

文章目录 1、简介2、观察者模式简单实现抽象主题&#xff08;Subject&#xff09;具体主题&#xff08;ConcreteSubject&#xff09;抽象观察者&#xff08;Observer&#xff09;具体观察者&#xff08;ConcrereObserver&#xff09;测试&#xff1a; 观察者设计模式优缺点观察…

DataEase开源BI工具安装_数据全量_增量同步_大屏拖拽自动生成_多数据源支持_数据血缘分析---大数据工作笔记0183

我这里用的是Centos7.9安装的 可以通过uname -p来查看一下我们的电脑架构,可以看到是x86_64架构的 我们下第一个,这个是x86架构的,第二个arm架构的 然后解压到/opt/module中 然后再去重命名一下文件夹. 推荐200G 本地模式的功能比较多 推荐100G

【FPGA IP系列】FIFO的通俗理解

FPGA厂商提供了丰富的IP核&#xff0c;基础性IP核都是可以直接免费调用的&#xff0c;比如FIFO、RAM等等。 本文主要介绍FIFO的一些基础知识&#xff0c;帮助大家能够理解FIFO的基础概念。 一、FIFO介绍 FIFO全称是First In First Out&#xff0c;即先进先出。 FIFO是一个数…

C语言第十一课--------操作符的使用与分类-------基本操作

作者前言 作者介绍&#xff1a; 作者id&#xff1a;老秦包你会&#xff0c; 简单介绍&#xff1a; 喜欢学习C语言和python等编程语言&#xff0c;是一位爱分享的博主&#xff0c;有兴趣的小可爱可以来互讨 个人主页::小小页面 gitee页面:秦大大 一个爱分享的小博主 欢迎小可爱们…

7.27 作业 QT

要求&#xff1a; 结果图&#xff1a; clock.pro: QT core gui QT texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated …

算法与数据结构(四)--排序算法

一.冒泡排序 原理图&#xff1a; 实现代码&#xff1a; /* 冒泡排序或者是沉底排序 *//* int arr[]: 排序目标数组,这里元素类型以整型为例; int len: 元素个数 */ void bubbleSort (elemType arr[], int len) {//为什么外循环小于len-1次&#xff1f;//考虑临界情况&#xf…

Power BI-云端报表定时刷新--ODBC、MySQL、Oracle等其他本地数据源的刷新(二)

ODBC数据源 一些小众的数据源无法直接连接&#xff0c;需要通过微软系统自带的应用“ODBC数据源”连接。 1.首次使用应安装对应数据库的ODBC驱动程序&#xff0c;Mysql的ODBC驱动需要手动安装 2.在web服务中进行数据源的配置 Mysql数据源 1.Powerbi与Gateway第一次连SQL…

Ansible安装部署与应用

文章目录 一、ansible简介二、ansible 环境安装部署三、ansible 命令行模块3.1 command 模块3.2 shell 模块3.3 cron 模块3.4 user 模块3.5 group 模块3.6 copy 模块3.7 file 模块3.8 hostname 模块3.9 ping 模块3.10 yum 模块3.11 service/systemd 模块3.12 script 模块3.13 m…

Staples Drop Ship EDI 需求分析

Staples 是一家美国零售公司&#xff0c;总部位于马萨诸塞州弗拉明汉&#xff0c;主要提供支持工作和学习的产品和服务。该公司于 1986 年在马萨诸塞州布莱顿开设了第一家门店。到 1996 年&#xff0c;该公司已跻身《财富》世界 500 强&#xff0c;后来又收购了办公用品公司 Qu…

Blazor前后端框架Known-V1.2.8

V1.2.8 Known是基于C#和Blazor开发的前后端分离快速开发框架&#xff0c;开箱即用&#xff0c;跨平台&#xff0c;一处代码&#xff0c;多处运行。 Gitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;https://github.com/known/Known 概述 基于C#和Blazor…

【文献分享】动态环境下竟然能实现实时语义RGB-D SLAM??

论文题目&#xff1a;Towards Real-time Semantic RGB-D SLAM in Dynamic Environments 中文题目&#xff1a;动态环境下实时语义RGB-D SLAM研究 作者&#xff1a;Tete Ji, Chen Wang, and Lihua Xie 作者机构&#xff1a;新加坡南洋理工大学电气与电子工程学院 卡内基梅隆大…

C++赋值运算符重载

运算符重载 C为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊函数名的函数函数名字&#xff1a;关键字operator后面接需要重载的运算符符号函数模型&#xff1a;返回值类型 operator操作符(参数列表) 注意事项&#xff1a; 1 不能通过连接其他符号…

【C++】开源:Muduo网络库配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Muduo网络库配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

网络知识整理

网络知识整理 网络拓扑网关默认网关 数据传输拓扑结构层面协议层面 网络拓扑 网关 连接两个不同的网络的设备都可以叫网关设备&#xff0c;网关的作用就是实现两个网络之间进行通讯与控制。 网关设备可以是交换机(三层及以上才能跨网络) 、路由器、启用了路由协议的服务器、代…