繁书简读之C++ Primer Day8: IO库

繁书简读之C++ Primer Day8: IO库IO库对象含义std::istream输入流,提供输入操作std::ostream输出流,提供输出操作std::cinstd::istream对

大家好,欢迎来到IT知识分享网。
繁书简读之C++

IO库

对象

含义

std::istream

输入流,提供输入操作

std::ostream

输出流,提供输出操作

std::cin

std::istream对象,从标准输入读取数据

std::cout

std::ostream对象,向标准输出写入数据

std::cerr

std::ostream对象,向标准错误写入数据

>>

从std::istream对象读取输入数据

<<

向std::ostream对象写入输出数据

getline函数

从std::istream对象读取一行,写入std::stringd对象

8.1 IO类

IO库类型头文件定义在三个头文件中

头文件

类型

含义

iostream

istream/wistream

输入流

ostream/wostream

输出流

iostream/wiostream

输入输出流

fstream

ifstream/wifstream

从文件读入

ofstream/wofstream

向文件写入

fstream/wfstream

从文件读入或向文件写入

sstream

istringstream/wistringstream

从字符串读入

ostringstream/wostringstream

写入到字符串

stringstream/wstringstream

从字符串读入或写入到字符串

1. 宽字符版本的IO类型和函数的名字以w开始,用来操作宽字符语言(wchar_t类型),如std::wcin, std::wcout和std::wcerr分别对应std::cin, std::cout和std::cerr。它们与其对应的普通char版本都定义在同一个头文件中

2. fstream和sstream中的类型都派生自iostream中的类型,实际应用中,通常将派生类对象当作基类对象使用

3. 输入流和输出流都是流对象,输入流就是用>>把流中内容保存到变量中,而输出流就是用<<把变量保存到流中,一个流是和控制台或一个文件或字符串相关联的

8.1.1 IO对象无拷贝或赋值

1. 不能拷贝或对IO对象赋值,所以IO对象也不能存在容器里

2. 由于IO对象不能拷贝,因此不能将函数形参或返回类型定义为流类型。

3. 进行IO操作的函数通常以引用方式返回流,读写一个IO对象会改变其状态,因此返回的引用不能是const的

8.1.2 条件状态

状态

含义

iostream::iostate

作为位集合提供了表达条件状态的完整功能,通过为运算符可以一次性检测或设置多个标志位

iostream::badbit/std::cin.badbit

表明流已经崩溃,是系统错误或不可恢复的读写错误,此时流已经不能再使用

iostream::failbit/std::cin.failbit

表明一个IO操作失败了,是可恢复错误

iostream::eofbit/std::cin.eofbit

表明流到达了文件结束

iostream::goodbit

表明流未处于错误状态,此值保证为零。

s.eof()

若流s的eofbit置位,则返回true

s.fail()

若流s的failbit置位,则返回true

s.bad()

若流s的badbit置位,则返回true

s.good()

若流s处于有效状态,则返回true

s.clear()

将流s中所有条件状态位复位,将流的状态设置成有效,返回void,执行clear操作后,s.good返回true

s.clear(flags)

将流s中指定的条件状态位复位,返回void

s.setstate(flags)

根据给定的标志位,将流s中对应的条件状态位置位,返回void

s.rdstate()

返回流s的当前条件状态,返回值类型为iostream::iostate

1. 注意:

a) 如果badbit/failbit/eofbit任何一个被置位,检测流状态的条件都会失败

b) good函数在所有错误均未置位时返回true,而bad,fail和eof函数在对应错误位被置位时返回true

c) 应该使用good或fail函数确定流的总体状态,eof和bad只能检测特定错误

8.1.3 管理输出缓冲

1. 每个输出流都管理一个缓冲区,用于保存程序读写的数据

2. 缓冲刷新(数据真实写入设备或文件)的原因:

a) 程序正常退出

b) 缓冲区满

c) 使用操作符std::endl/std::flush/std::ends显示刷新缓冲区

i. std::endl:输出一个换行符并刷新缓冲区

ii. std::flush:刷新流,但不添加任何字符

iii. std::ends:在缓冲区插入空字符,然后刷新

iv. std::unibuf:告知流接下来每次操作之后都要进行一次flush操作

v. std::nounitbuf:重置流,回到正常缓冲方式

std::cout << std::unitbuf; // 所有写操作都会立即刷新 std::cout << std::nounitbuf; // 回到正常的缓冲状态

3. 当一个输入流关联到一个输出流,每次从输入流读取数据前都会先刷新关联的输出流。默认情况下,std::cin和std::cerr都关联到std::cout,因此,读std::cin或写std::cerr都会刷新std::cout的缓冲区

4. 使用tie函数可以关联两个流。它有两个重载版本:无参版本返回指向输出流的指针。如果本对象已关联到一个输出流,则返回的就是指向这个流的指针,否则返回空指针。tie的第二个版本接受一个指向ostream的指针,将本对象关联到此ostream

std::cin.tie(&std::cout); //std::cin对象关联到std::cout对象 std::ostream *old_tie = std::cin.tie(nullptr); //std::cin不再关联其他流对象 std::cin.tie(&std::cerr); // 从std::cin对象读取数据之前会自动刷新std::cerr std::cin.tie(old_tie); //重新将std::cin对象关联到std::cout对象

5. 每个流同时最多关联一个流,但多个流可以同时关联同一个ostream,向tie传递空指针可以解开流的关联

8.2 文件输入输出

1. 头文件fstream定义了三个类型来支持文件IO:ifstream从给定文件读取数据,ofstream向指定文件写入数据,fstream可以同时读写指定文件

操作

含义

std::fstream fstrm

创建一个未绑定到任何文件的文件流

std::fstream fstrm(s)

创建一个绑定到文件s的文件流并打开它,s是一个文件路径,C++11及以后,它可以是std::string类型或者是C风格字符串

std::fstream fstrm(s, mode)

与上一条类似,但是要多指定一个给定的模式

fstrm.open(s)

先定义fstrm对象,再执行open操作

fstrm.open(s, mode)

fstrm.close()

关闭fstrm对象绑定的文件

fstrm.is_open()

判断和fstrm对象绑定的文件是否被成功打开并且未被关闭,返回bool

8.2.1 使用文件流对象

1. 创建文件流对象时,如果提供了文件名(可选),open会被自动调用

std::ifstream in(ifile); //创建输入文件流并打开指定文件ifile std::ofstream out; // 创建输出文件流,但未绑定文件

2. 在要求使用基类对象的地方,可以用继承类型的对象代替。因此一个接受iostream类型引用或指针参数的函数,可以用对应的fstream类型来调用

3. 如果open调用失败,failbit会被置位,建议每次执行open操作后,用is_open判断打开是否成功

4. 如果想将文件流关联到另一个文件,必须先调用close关闭当前文件,再调用clear重置流的条件状态(close不会重置流的条件状态)

5. close函数不需要强制调用,一旦fstream对象销毁了,会自动调用close函数关闭该对象绑定的文件

8.2.2 文件模式

模式

含义

in

以只读模式打开

out

以只写模式打开

app

每次写操作前均定位到文件尾

ate

打开文件后即定位到文件末尾

trunc

截断文件

binary

以二进制方式进行IO

1. 注意

a) 只能对std::ofstream或std::fstream对象设定out模式

b) 只能对std::ifstream或std::fstream对象设定in模式

c) 只有设定了out,才能设定trunc模式,只设置out默认也会设置trunc

d) 只要trunc没被设定,就能设定app模式,在app模式下,即使没有设定out模式,文件也是以输出方式打开。

e) 如果想保留以out模式打开的文件内容,就必须同时设定app模式,这会将数据追加写到文件末尾;或者同时设定in模式,即同时进行读写操作

f) ate和binary模式可用于任何类型的文件流对象,并可以和其他任何模式组合使用。

g) 与std::ifstream对象关联的文件默认以in模式打开,与std::ofstream对象关联的文件默认以out模式打开,与fstream对象关联的文件默认以in和out模式打开

h) 默认情况下,打开std::ofstream对象时,文件内容会被丢弃,阻止文件清空的方法是同时指定app或in模式

8.3 string流

头文件sstream定义了三个类型来支持内存IO:istringstream从string读取数据,ostringstream向string写入数据,stringstream可以同时读写string的数据

方法

含义

sstream strm

定义一个未绑定的stringstream对象,sstream是sstream头文件中定义的类型中的一种

sstream strm(s)

strm中保存着string s的备份,这也是用std::string类型构造sstream对象的一种方式

strm.str()

返回strm当中保存的string的备份

strm.str(s)

将string s拷贝到strm对象内,返回void

8.3.1 使用istringstream

struct Contact //单个联系人信息 { std::string name; std::vector<std::string> emails; }; std::string line; //用于保存整行 std::string email; //用于保存邮件 std::vector< Contact > contacts; //用于保存所有联系人信息 while (getline(cin, line)) { Contact info; std::istringstream record(line); //用读入的一行初始化stringstream对象 record >> info.name; //保存联系人姓名 while (record >> email) //按空格保存多个邮件地址 info.emails.push_back(email); contacts.push_back(info);按行保存联系人信息 }

8.3.2 使用ostringstream

for (auto &entry : contacts) { std::ostringstream validEmail, invalidEmail;//存储有效和非法邮箱 for (auto &email : entry.emails)//便利每个联系人的邮箱列表 { if (!valid(email)) invalidEmail << " " << email; else validEmail << " " << email; } if (invalidEmail.str().empty()) //如果不存在非法邮箱 std::cout << entry.name << " " << validEmail.str() << std::endl; else std::cerr << "input error: " << entry.name << " invalid email " << invalidEmail.str() << std::endl; }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/59288.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信