C++【流】

一、关于流的概念和一些基本关系

1.流的概念

流(stream)在C++中指字节流,其实就是1010这样的二进制,以字节为单位在程序和外部流动。打个比方,流可以看成一个官职,名叫河道监管,负责管理河道的水流流向。水流既可以流向田地,灌溉桑田,也可以流向江河湖泊。输入流就是让数据从外部(键盘、文件、内存、等)流向程序,输出流就是让数据从程序流出到外部(屏幕、文件、打印机等)。

2.基本关系

首先需要明确几个常见的类:ios类(模板类),ios_base类(非模板类),ostream类,istream类,iostream类。他们的关系还是可以用河道监管这个职位来描述。首先,皇帝建立了河道监管这个职位,需要派人上任。第一任河道监管的名字叫做ios_base类。后来,ios_base类把位置传给了它儿子,也就是ios类。ios类子承父业,并且修建了一座水库便于调水。不过ios类觉得自己干太累,于是他建立了几个新官职,一个负责管理水库(缓冲区内存),即streambuf类。一个负责正向调水(输出),一个负责反向调水(输入),也就是ostream类和istream类。后来,ostream和istream类为了把自己的调水技能传承下去,决定联姻,生出了一个既能正向调水,也能反向调水的人才,叫做iostream类。下图来自C++ Primer Plus一书。

从用途分类,C++中常用的有三种流,一种是用于控制台的流(istream, ostream, iostream),也就是常见的从键盘输入,屏幕输出的流。上述例子就是说的这个。此外,还有文件流(ifstream, ofstream, fstream)用于文件读写、以及字符串流(istringstream,ostringstream, stringstream)常用于实现字符串到其他数据类型的转换。

上图不是很完整,比如ofstream类是ostream类的派生类,ifstream类是istream类的派生类。fstream类是iostream类的派生类。

接下来从这三种流的角度出发,分别说明其重点。

二、三流重点

2.1 输入输出流(iostream)

对象:

iostream类是一个类,既然是类,就要用类创建对象。包含<iostream>头文件后,系统会创建8个对象,分别是cin、cout、cerr、clog以及wcin、wcout、wcerr、wclog。后四个与前四个作用类似,不同点在于后者处理的数据类型为wchar_t类型。

· cin对象对应于标准输入流,默认情况下关联到标准输入设备(键盘)

· cout对象对应于标准输出流,默认情况下关联到标准输出设备(显示器)

· cerr对象对应于标准错误流,用于显示错误信息。默认情况下关联到标准输出设备(显示器)。这个流没有缓冲区,信息将直接发送给屏幕而不是等着你敲回车

· clog对象与cerr对象类似,也对应于标准错误流,默认情况下关联到标准输出设备(显示器),但有缓冲区。


成员函数:

iostream类继承了istream类和ostream类,所以需要知道这两类中常用的一些函数。

·ostream类:

① 重载运算符<<,可用于所有基本的数据类型,但如果是自定义类型需要重载后使用。

② put()和write()函数。前者用于显示字符,后者用于显示字符串。

·istream类:

① 重载运算符>>,可用于所有基本的数据类型,但如果是自定义类型需要重载后使用。

②get()和getline(),用于获取字符。两者都可以遇到换行符或者到指定最大字符时停止。区别在于get将换行符保留在缓冲区,getline将其丢弃。

③ ignore(),用于抛弃字符。

④ 其他不常用的:read(),用于读字符;peek(),用于查看下一个字符;gcount(),用于返回最后一个非格式化抽取方法读取的字符数(不是由抽取操作符(>>)读取的);putback()用于将一个字符插入到输入字符串中。被插入的字符是下一条语句读取的第一个字符。


cin:

从键盘读取数据,遇到空格、换行符结束。cin不会丢弃换行符,也就是把换行符留在了缓冲区,但当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符

如果遇到类型不匹配的字符,cin会读取失败并返回0;

cin.get()和cin.getline():

cin.get()中,括号里不加任何东西,作用是只读一个字符,即使是一个换行符。

cin.get(char),读取一个字符。

cin.get(字符串地址,大小),读一行字符,到换行或最大个数时停止。

注:get函数不会丢弃换行符,会将其留在缓冲区。

cin.getline(字符串地址,大小),读一行字符,到换行或最大个数时停止。

注:cin.getline函数会丢弃换行符,不会将其留在缓冲区。

注:getline(cin,str)是string类的函数,跟cin.getline不一样。

优缺点:getline的优点是不会在缓冲区留下东西,但缺点是无法确定是读完一行遇到换行符停止还是到达字符数量上限停止。get更适用于判断是否读完一行。也就是说可以在读完一行后加一个get()函数,如果get()读取到了换行符,说明get函数完整的读完一整行。

cout:

console output(控制台输出)。cout用起来比较简单,但在搜查相关资料的时候,发现了一个很有趣的问题。先看这个看似简单的题:

int i=1;

cout<<++i<<i++<<i<<i++<<++i<<endl;

这两行代码会输出什么?我刚开始想,很简单嘛,2,2,3,3,5。但是不同的编译器结果不一样。Visio Studio和g++编译的结果是53525,VS code编译的结果是22335。为什么会产生53525的结果?首先,这个结果说明cout连续输出时是从右往左处理数据的,并且把数据放在类似于栈的结构中。这样,结果就变成了53322。但是还有一个点,i++和++i的区别。++i和i共用一个地址,但i++返回一个新地址(可以自己写一个程序观察一下内存地址的区别)。因此,最终输出的++i和i应该是相等的,结果应该是53525。

调整字段宽度:cout.width(int i);(只影响接下来一个)

填充字符:cout.fill(‘*’);(接下来的都有效)

设置精度:cout.presision(精度);(接下来的都有效,且精度指小数点后面的位数)

setf()函数,输出格式设置。有多种形式,用的时候自己看。

2.2 文件流(fstream)

ofstream 程序写入文件

使用方法:

① 创建ofstream对象

② 与文件关联  如:对象.open(“文件名”) 注:open()和close()要成对用

③ 像用cout一样用创建好的对象

ifstream的使用方法同理。

流状态检查:is_open()

二进制输入输出:read()、write()

2.3 字符串流(sstream)

https://www.bilibili.com/video/BV13r4y1w7nC?spm_id_from=333.880.my_history.page.click&vd_source=08e671d7e4b88d1170c01942ff4e0dd6

三、边角料

1.河道监管只负责水流的流向,不负责水流从哪儿来,到哪儿去。至于具体的来源去向,还是要听上级的指挥。这种相对独立的思想是C++中常见的一种思想。

2.一般来说不带.h的C++标准库头文件都需要用到命名空间std。流也一样,std就相当于朝廷,不论河道监管还是手底下的cin、cout等都属于朝廷指定的官职,必须打着朝廷的名号用。所以在使用时需要声明:我是朝廷的命官!

写的不是很完整,因为我也是初学者。但写都写了 等用到学到新东西再进行补充。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容

  • 这里主要是讨论fstream的内容: 1.打开文件 在fstream类中,成员函数open()实现打开文件的操作,...
    cjhfhb阅读 278评论 0 0
  • 1.流的概念和流类库的结构 程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件...
    无涯之涯阅读 195评论 0 0
  • I/O流的概念 程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。 C++输...
    青春猪头少年_阅读 490评论 0 0
  • c++的输入输出不是建立在语言上的,而是由iostream和fstream文件中定义的一组模板类实现的,且这个类库...
    Tianql阅读 3,307评论 0 1
  • 第八章 c++输入和输出流 8.1 流的概念和流类库的结构 程序的输入指的是从输入文件将数据传送给程序,程序的输出...
    CodeDove阅读 714评论 0 3