C++ IO库
来源:互联网 发布:怎么查域名是否备案 编辑:程序博客网 时间:2024/05/29 04:27
IO就是input和output和起来的缩写,在C++语言当中读写文件,控制台操作或者是磁盘以及内存读写都可以通过C++当中IO库来实现。网络上有许多关于io库的介绍,本文主要记录自己在实验当中情况、查阅资料的理解,以及对其他之前的高人博客内容的总结,参考资料是C++ primer第5版。
IO类
书中首先介绍了3个头文件,分别是
- < iostream > 定义了读写流的基本类型
- —->istream 从流当中读取数据
- —->wistream 宽字符版本,从流当中读取数据
- —->ostream 向流当中写入数据
- —->wostream 宽字符版本,向流当中写入数据
- —->iostream 读写流
- —->wiostream 宽字符读写流
- < fstream >定义了读写命名文件的类型
- —->ifstream,wifstream 从文件读取数据
- —->ostream,wofstream 向文件写入数据
- —->fstream,wfstream 读写文件
- < sstream >
- —->istringstream,wistringstream 从string读取数据
- —->ostringstream, wostringstream 向string写入数据
- —->stringstream,wstringstream 读写string
w字母开头的是为了支持使用宽字符的语言,wcin、wcout、wcerr分别对应cin、cout、cerr。
还没有用过宽字符型,自己敲了两下。宽字符型用cin和cout果然不好使,呵呵
#include <bits/stdc++.h>using namespace std;int main(){ ios::sync_with_stdio(false); wchar_t c; wcin>>c; wcout<<c<<endl; return 0;}
###IO类型之间的关系
C++的标准库可以忽略掉不同类型在流操作这件的差异,这是用过继承实现的。例如,ifstream和istringstream都继承自istream。类似的继承如下,图片来自http://en.cppreference.com/w/cpp/io
因为继承关系的性质,可以把一个派生类对象当做基类对象使用,那么就可以使用ifstream和istringstream像使用cin一样去使用上面的这些对象。
比如经常会用到读取文件,写入文件的操作,以及把int转换成string的操作。
#include <bits/stdc++.h>using namespace std;fstream in;int main(){ ios::sync_with_stdio(false); int a; in.open("data.txt");//里面放了一个整数 in>>a;//像cin一样去使用 cout<<a<<endl;//输出读出的数据 in.close();//关闭文件流 return 0;}
下面的代码是字符串转换成整数,然后加上1
#include <bits/stdc++.h>using namespace std;int main(){ ios::sync_with_stdio(false); stringstream ss; string s; int a; cin>>s; ss<<s;//stringstream可以像cin一样去使用,得益于继承的机制 ss>>a; cout<<a+1<<endl; return 0;}
###IO对象没有拷贝或赋值
不能够将形参或返回类型设置为流类型,进行io操作的函数通常以引用的方式传递和返回流,读写io对象会改变其状态,因此传递和返回的引用不能是const的。
书上代码
ofstream out1,out2;out1=out2;//错误,不能赋值ofstream print(ofstream);//错误,不能初始化out2=print(out2);//错误,不能拷贝
IO的条件状态
其中iostate有四个值,分别是failbit, eofbit, badbit和goodbit
iostate拥有这四种状态,这四种状态是iostate的一个具体值。
通过代码输出结果
void state(){ cout<<istream::goodbit<<endl; cout<<istream::badbit<<endl; cout<<istream::eofbit<<endl; cout<<istream::failbit<<endl;}
如果代码里面仅仅输出状态,得到的结果是0,1,2,4。分别为iostate对应二进制的状态,这些状态可以用”|”运算符来组合使用。
000
001
010
100
找一个字符串流测试一下,代码来自cpp官网
#include <bits/stdc++.h>using namespace std;void print_state (const std::ios& stream) { std::cout << " good()=" << stream.good(); std::cout << " eof()=" << stream.eof(); std::cout << " fail()=" << stream.fail(); std::cout << " bad()=" << stream.bad(); }int main () { std::stringstream stream; stream.clear (stream.goodbit); std::cout << "goodbit:"; print_state(stream); std::cout << '\n'; stream.clear (stream.eofbit); std::cout << " eofbit:"; print_state(stream); std::cout << '\n'; stream.clear (stream.failbit); std::cout << "failbit:"; print_state(stream); std::cout << '\n'; stream.clear (stream.badbit); std::cout << " badbit:"; print_state(stream); std::cout << '\n'; return 0;}
结果可以运行一下看看,输出如下
goodbit: good()=1 eof()=0 fail()=0 bad()=0 eofbit: good()=0 eof()=1 fail()=0 bad()=0failbit: good()=0 eof()=0 fail()=1 bad()=0 badbit: good()=0 eof()=0 fail()=1 bad()=1
这里先拿cin写一个测试的例子,书上举例说给一个整数读入字符串会出现错误,那会出现什么错误呢?
#include <bits/stdc++.h>using namespace std;int main (){ int val; cout<<cin.rdstate()<<endl;//最初的cin的状态 cout<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; //输出cin各项状态值 cin>>val;//输入一个123试试 cout<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; cin.clear();//清空,重置cin的状态为iostream::good cin>>val;//输入qwe cout<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; return 0;}
首先输出
0
1000
输入123后
1000
输入qwe后
0010
现在增加一个重新置位
#include <bits/stdc++.h>using namespace std;int main (){ int val; cout<<cin.rdstate()<<endl;//最初的cin的状态 cout<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; //输出cin各项状态值 cin>>val;//输入一个123试试 cout<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; cin.clear();//清空,重置cin的状态为iostream::good cin>>val;//输入qwe cout<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl;// cin.clear();//清空重置后结果 cin.clear(std::iostream::goodbit);//效果同上 cout<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; return 0;}
清空后输出结果就是1000了,因为cin被重新置位成了good
现在贴一个检查文件是否存在的,如果文件存在读入一个整数。如果文件不存在,输出错误,如果读到文件尾部,输出end of file!
#include <bits/stdc++.h>using namespace std;int main (){ ifstream is; int a; is.open ("data.txt"); if ( (is.rdstate() & ifstream::failbit ) != 0 ) { cerr << "Error opening !"; return 0; } else { while(!is.eof()) { is>>a; if(is.good()) cout<<a<<endl; else cerr<<"end of file!"<<endl; } } is.close();}
首先先判断打开的文件是否存在,如果不存在则输出error opening!
while(!is.eof())的应用,如果is读取到文件尾部会设置eofbit状态,但是不会返回0,而是继续读取,所以如果读到了结尾还会在输出一次最后一行。这里用判断is.good()的方式来判断流是否正确。
刷新缓冲区
缓冲区就是把输入输出的放到内存当中,使用时再从内存当中取出。这样做的目的可以让cpu和硬件设施比如打印机之类的东西协调。
导致缓冲刷新的原因:
- 程序正常结束
- 缓冲区满了
- 使用endl(经常当换行使用了 呵呵)
- 使用unitbuf
- 一个输出流被关联到另一个流
如何刷新?
- endl操作符,用于输出一个换行符并刷新缓冲区
- flush操作符,用于刷新流,但不在输出中添加任何字符
- ends操作符,在缓冲区中插入空字符null,然后刷新
- 刷新所有输出,unitbuf操作
- 关联输入输出流
#include <bits/stdc++.h>using namespace std;int main (){ cout<<"hi"<<endl; cout<<"hi"<<flush; cout<<"hi"<<ends; cout<<unitbuf;//全刷新 return 0;}
如何关联输入输出?使用tie函数,它返回指向输出流的指针。
#include <bits/stdc++.h>using namespace std;int main(){ ofstream out("data.txt");//放这个文件里面写东西 cin.tie(&out);//把cin关联到out上面 out<<123;//写入文件 int val;// cin>>val;//只要使用cin,就会刷新输出流,这样123就被写进data.txt return 0;}
to be continue~
- C++IO库
- C++IO库
- 【C++】标准IO库
- C++------IO库
- IO库(c++)
- C++primer 标准IO库
- C++Primer 标准IO库
- C++_Primer_chapter8 标准IO库
- c标准IO库使用
- c++io
- 【Linux】系统IO和标准C库IO函数
- 《C++primer》 函数 标准IO库
- IO之标准C库buffer
- c++Primer,八,标准IO库
- C标准库:IO错误处理
- C标准库之文件IO操作
- IO之标准C库buffer
- 对C++IO库的一点理解
- TCP协议中的三次握手和四次挥手(图解)
- JavaScript节点操作
- DataBinding学习入门篇
- Educational Codeforces Round 15
- Fedora 24下安装Chrome浏览器
- C++ IO库
- 生活感触
- 几个常见的DP问题及解法
- Android 消息推送
- Android SQLite数据库版本升级原理解析
- 2016/8/1 报道
- Android客户端和php+mysql+apache搭建的服务器之间的简单交互
- 六大设计原则---单一职能原则
- Mac 安装和卸载 Mysql5.7.11 的方法