大家好,欢迎来到IT知识分享网。
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