C++三大IO流类总结——标准IO流、文件IO流、内存IO流
IO流类一览
- ios:流基类(抽象类)
- istream:通用输入流类和其他输入流的基类
- ostream:通用输出流类和其他输出类的基类
- iostream:通用输入输出流类和其他输入输出流类的基类
- ifstream:输入文件流类
- ofstream:输出文件流类
- fstream:输入输出文件流
- istrstream:输入字符串流类
- ostrstream:输出字符串流类
- strstream:输入输出字符串类
- iostream_withassign: 通用输入输出流类和其他输入输出流类iostream的的派生类
关系图如下:
派生
派生
派生
派生
派生
派生
派生
派生
派生 ios类:流基类 istream:通用输入流类 ostream:通用输出流类 iostream:通用输入输出类 ifstream:输入文件流类 istringstream:输入字符串流类 ofstream:输出文件流类 ostringstream:输出字符串流类 fstream:输入输出文件流类 stringstream:输入输出字符串流类
标准IO流
C++中包含几个预定义的流对象,即标准IO流,它们是标准输入流对象cin、标准输出流对象cout、非缓冲型的标准出错流对象cerr、缓冲型的标准出错流对象clog。
- cin是istream的派生类istream_withassign的对象,它与标准输入设备(通常是键盘)相联系。
- cout是ostream的派生类ostream_withassign的对象,它与标准输出设备(通常是显示器)相联系。
- cerr是ostream的派生类ostream_withassign的对象,它与标准错误输入设备(通常是显示器)相联系。
- clog是ostream的派生类ostream_withassign的对象,它与标准错误输入设备(通常是显示器)相联系。
标准IO流的条件状态
C++语言IO类中定义了一些函数和标志,可以用来访问IO流的条件状态。
一旦一个流发生错误,对其进行IO操作都无法进行。可以将流作为条件判断,这也是最简单的一种方式,但这样无法知晓 流的具体错误。通过IO类中的条件状态函数,可以知道流操作为什么失败。
条件状态标志
strm::iostate
:条件状态集合
strm::badbit
:指示流是否崩溃
strm::failbit
:表示一个IO操作失败
strm::eofbit
:表示到流遇到结束标志
strm::goodbit
:表示流正常使用
条件状态函数
对于标准IO流s,有如下成员函数
s.setstate(flag)
:将流s状态置为flag,返回void
s.rdstate()
:返回流s的当前状态,返回类型为strm::iostate
s.eof()
:若eofbit置位则返回true,表示到达流s末尾
s.fail()
:若badbit或failbit置位,则返回true
s.good()
:若流s处于有效状态,则返回true
s.clear()
:清空各个状态位,将流置为有效
s.clear(flag)
:复位flag中设置的标志位。可以先使用rdstate()
读取到流标志位,进行位操作,作为flag参数传入。
标准IO流的输入输出成员函数
put函数
put函数用于输出一个字符格式:cout.put(char ch)
例如:输出A可以采用以下方法:
cout.put('A'); cout.put(65) ; cout.put(25+40);
get函数
get函数的功能与提取运算符>>类似,主要不同之处是get函数在读入数据时可以包括空白字符,而后者不可以。- get函数用于读入一个字符,调用形式:
cin.get()
- get函数用于传入一个字符到char型变量,调用形式:
cin.get(char ch)
- get函数用于读入一个字符,调用形式:
getline函数
getline函数用于从输入流读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组),然后插入一个字符串结束志”\n”。(“\n”可以用其他字符代替)遇到’\n‘会提前终止读取字符。getline函数调用格式:
- cin.getline(字符数组,字符个数n,终止标志字符)
- cin.getline(字符指针,字符个数n,终止标志字符)
ignore函数
ignore函数的功能是跳过输入流的n个字符(默认的个数为1),或在遇到指定的终止符时 提前结束。
调用格式:cin.ignore(n,终止字符);cin.ignore();cin.ignore(1,EOF)
代码示例
条件状态
#include <iostream>
using namespace std;
int main() {
cout<<"初始状态:"<<endl;
//cout<<"failbit: "<<cin.failbit<<endl;
cout<<"fail(): "<<cin.fail()<<endl;
//cout<<"badbit: "<<cin.badbit<<endl;
cout<<"bad(): "<<cin.bad()<<endl;
//cout<<"eofbit: "<<cin.eofbit<<endl;
cout<<"eof(): "<<cin.eof()<<endl;
//cout<<"goodbit: "<<cin.goodbit<<endl;
cout<<"good(): "<<cin.good()<<endl;
int i;
cout<<"在这里我们输入EOF:"<<endl;
cin>>i;
cout<<"输入EOF后:"<<endl;
cout<<"fail(): "<<cin.fail()<<endl;
cout<<"bad(): "<<cin.bad()<<endl;
cout<<"eof(): "<<cin.eof()<<endl;
cout<<"good(): "<<cin.good()<<endl;
cout<<"先clear(),在这里我们正常输入一个数字:"<<endl;
cin.clear();
cin>>i;
cout<<"正常输入数字后:"<<endl;
cout<<"fail(): "<<cin.fail()<<endl;
cout<<"bad(): "<<cin.bad()<<endl;
cout<<"eof(): "<<cin.eof()<<endl;
cout<<"good(): "<<cin.good()<<endl;
cout<<"在这里我们输入一个字符串:"<<endl;
cin>>i;
cout<<"输入字符串后:"<<endl;
cout<<"fail(): "<<cin.fail()<<endl;
cout<<"bad(): "<<cin.bad()<<endl;
cout<<"eof(): "<<cin.eof()<<endl;
cout<<"good(): "<<cin.good()<<endl;
return 0;
}
put和get函数
#include<iostream>
using namespace std;
int main()
{
char ch;
cout<<"Input:";
while(cin.get(ch)) //读取输入的字符,直到结束为止
{
cout.put(ch); //输出字符
}
return 0;
}
/* 程序运行结果是: input:123 abc xyz 123 abc xyz */
getline函数
#include<iostream>
using namespace std;
int main()
{
char ch[20];
cout<<"输入一行字符:"<<endl;
cin.getline(ch,21,'t');
cout<<ch<<endl;;
return 0;
}
/* 程序运行结果是: 输入一行字符: shdfjsfefrsdfjt shdfjsfefrsdfj */
标准IO的格式控制
输出格式控制
缓冲区控制
<<endl
: 输出换行符, 刷新缓冲区<<ends
: 输出空字符, 刷新缓冲区flush
: 刷新缓冲区
控制bool类型格式
<<boolalpha
: 输出true 或者 false<<noboolalpha
: 输出0或1
进制控制
<<oct
: 八进制格式输出<<dec
: 十进制格式输出<<hex
: 十六进制格式输出<<showbase
: 输出指明进制类型, 0代表八进制,0x代表16进制<<noshowbase
: 输出不指明进制类型
其他常用输出格式控制
cout.precision(int n)
或者cout<<prcision(int n)
: 设置浮点数打印位数为n<<showwpoint
: 总是打印浮点数小数点<<noshowpoint
: 有小数部分才打印小数点<<setw(int n)
: 指定打印宽度为n<<left'或
<<right`: 设置左对齐或者右对齐(默认对齐)<<setfill(char ch)
: 设定填充字符,默认是空格
输入格式控制
>>skipws
: 输入跳过空白符>>noskipws
: 输入不跳过空白符
文件输入输出流
根据继承关系可以知道,文件输入输出流继承了iostream流类的所有成员函数,同时多了一些自身特有的成员函数和操作如下:
文件流的关联
fin.open(“test.txt”,ios::binary) //从文件读取数据
fout.open(“test.txt”,ios::binary) //输出到文件,向文件写数据
fboth.open(“test.txt”,ios::in|ios::out|ios::binary) //读写都可以
或者
ifstream fin(“test.txt”,ios::binary)
ofstream fout(“test.txt”,ios::binary)
fstream fboth(“test.txt”,ios::in|ios::out|ios::binary)标志位含义:
ios::in 打开文件做读操作
ios::out 打开文件做写操作,会删除原有数据
ios::app 在每次写之前找到文件尾
ios::trunc 打开文件时清空已存在的文件流
ios::ate 打开文件后立即定位到文件末尾
ios::binary 以二进制模式进行IO操作
ios::nocreate: 不建立文件,所以文件不存在时打开失败
ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败文件流的关闭: 调用close()成员函数
字符串输入输出流类
字符串流和文件流操作基本一致相同,区别在于:
- 输出时数据不是流向外存文件,而是流向内存中的一个存储空间。输入时从内存中的存储空间读取数据,因此又称内存输入输出流类.
- 字符串流对象关联的不是文件,而是内存中的一个存储空间,因此不需要打开和关闭文件。