@C++使用类型安全的I/O,任何一次I/O都是对数据类型敏感的。
@用户可以通过重载流运算符来实现对用户自定义类型的I/O操作,这种扩展很拉风。
@C++的I/O是以一连串的字节流的方式进行的。
@C++同时提供低层次的和高层次的I/O。低层次的I/O即是非格式化的I/O,指定字节从设备流向内存或者从内存流向设备,
这种传输速度快,针对字节,但不方便,非格式化的I/O,也就是高层次的I/O,字节被组成有意义的字符,方便。
@使用非格式化的I/O可能会导致移植问题,因为是基于字节。
@绝大多数C++程序包含<iostream>该头文件声明了所有I/O操作所需的基础服务,此文件中定义了cin(标准输入),
cout(标准输出),cerr(无缓冲的标准错误流),clog(有缓冲的标准错误流)
@<iomanip>头文件中声明了对于带有参数化流运算符的格式化和非格式化的服务,就是带有参数的流运算符,跟函数差不多的形式,
不带参数的流运算符不用添加这个头文件。
@对于文件的I/O,添加<fstream>
@<iostream>提供了很多类模板来处理I/O操作,例如basic_istream(处理输入操作),basic_ostream(支持输出操作),basic_iostream(都支持)
当然,那样用起来麻烦些,在iostream中使用typedef定义了其别名,istream,ostream,iostream。
@注意typedef只是创建了一个名字,并没有创建别名。
@cerr是一个ostream实例,被连接到标准错误设备,对象cerr的输出是无缓冲的,这意味着每个针对cerr的输出必须被立即显示。
@clog是一个ostream实例,被连接到标准错误设备,clog的输出是有缓冲的,这表示每个针对clog的流将被保存到缓冲区,直到缓冲区被填满或被清空才输出。
@ 输出大体包括
1,使用流插入运算符执行标准数据类型的输出。
2,使用put成员函数进行字符输出
3,通过write函数进行非格式化输出
4,十进制,八进制,十六进制的输出
5,不同精确度的浮点数输出
6,指定域宽的输出
7,带有特殊填充字符的输出
8,科学计数或带有十六进制符号的输出
@c++能自动判定类型,所以会自动把char×当作以空字符结尾的字符串,而如果要打印其首地址怎么办?,解决办法就是强制把char×转换成void×,如果程序员想输出一个地址,都必须这样办。
例子:
const char × const word =“hello”;
cout<<word;
cout<<static_cast<void*>(word);
@可以使用cout的成员函数put输出单个字符,cout.put('A‘);cout.put('A‘).put(’\n‘);
@ 输入流
1, 没有实参的get函数返回一个字符(包括空白字符等)
2,eof函数用来判断cin流是否读到文件尾。
while(charac=cin.get()!=EOF)
cout.put(charac);
3,带有一个参数的get函数,将把读入的字符存储在参数中。
4,含有3个参数的get函数,第一个是一个字符数组,第二个是一个长度,第三个是分隔符,注意:在读取时遇到分隔符,
读取终止后分隔符没有被放入到数组,而是仍旧在输入流中,默认的分隔符是\n,读取的最大字符是n-1,因为最后一个要是空字符。
例子cin.get(buffer,size);
5,getline与有三个参数的get类似,但是会从输入流中移除分隔符,没有放在字符数组中。
6,函数ignore或者是读取并丢弃一定数量的字符,或者是遇到指定分隔符时停止(默认是EOF)
7,putback将先前用get获取的字符再放回到输入流中(最前面,下一个将读到的字符)
8,peek将返回输入流中的下一个字符,但不将它从输入流中丢弃。
@非格式化的读入和输出。
读入使用cin.read,输出使用cout.write,read将一定数量的字节读入到数组中,这些字节没有经过任何格式化。
char buffer[]=“hello world";
cout.write(buffer,6);
输出buffer的前6个字符。
read将指定数量的字符读入到字符数组中,当读取的字符数量少于指定数量时,failbit将被设置。
成员函数gcount返回最近一次操作读取的字符。
char buffer[80];
cin.read(buffer,40);
cout.write(buffer,cin.gcount());
@ 流操作符, 设置域宽,设置精度,十六进制,八进制等,注意有参数的流操作符要加头文件<iomanip>
1,进制
cout<<dec<<integer;
cout<<hex<<integer;
cout<<oct<<integer;
也可以通过setbase,setbase(16);直观方便。
cout<<setbase(16)<<integer;
2,浮点进度
可以使用setprecision(n)流运算符,或者ios_base的precision来控制精度,这两个都是有粘性的(影响后面所有的输出)
注意在使用之前,加上cout<<fixed;以表示使用定点格式。
cout<<setprecision(n)<<doubleNumber;
cout.precision(3);
cout<<doubleNumber;
for(int i=0;i<10;i++)
cout<<setprecision(i)<<doubleNumber;
3,域宽
成员函数width可以设置域宽(ios_base)并返回原来的域宽,域宽不是粘性的,不会影响下一个输出,setw流操作符也可以用来设置域宽。
注意:当向一个char字符数组输入数据时,读入的最大字符数将小于制定域宽的字符,因为必须在输入的字符串中插入空字符。
cin.width(5);
while(cin>>array)
{
cout.width(n++);
cout<<array;
cin.width(5);
}
程序员可以创建自己的流操作符,例如下面创建的4个流操作符。(对于输出流操作符来说,它的返回类型和参数都必须是ostream&
ostream& bell(ostream& output)
{
return output<<'\a';
}
ostream& munipulator(ostream& output)
{
return output<<‘\a';
}
ostream& tab(ostream& output)
{
return output<<'\t';
}
ostream& endLine(ostream& output)
{
return output<<'\n'<<flush;
}
@流的格式状态和流操作符
1,流操作符showpoint强制要求浮点数的输出必须带小数点和尾数0
可以使用noshowpoint重置。
cout<<showpoint<<9.00;
cout<<noshowpoint;
2,对齐
使用left,right流操作符对齐,通常与setw,width一起使用。
刘操作副internal表示数字的符好左对齐,数字右对齐,中间部分可以使用填充,注意可以使用showpos强制输出正数的"+";
fill成员函数通常用来对对齐域进行填充,相同的还有setfill流运算符
注意看下面的区别
cout.fill(‘×’);
cout<<setw(10)<<"heh";
cout<<internal<<setw(10)<<setfill('>')<<hex<<integer;
3,showbase与dec,hex,oct使用时可以以10,16,8进制形式显示数字
cout<<showbase;
cout<<integer;
cout<<hex<<integer;
cout<<oct<<integer;
4,scientific以科学计数发现是,fixed以指定格式小数显示,默认6位。
5,uppercase,以大写显示,取消使用nouppercase
cout<<uppercase<<4。34e10<<endl<<hex<<showbase<<123456;
6,布尔格式。
默认输出布尔格式是0或1,可以使用流运算符boolalpha设置流以字符串形式显示bool值,可以使用noboolalpha取消。
cout<<bool;
cout<<boolalpha<<bool;
@恢复状态
以上是怎样设置格式状态,假设要恢复到以前的状态需要两个内容。
1,需要ios_base里的成员类型fmtflags,这里面保存格式的状态信息。
2,cout的函数flags,这个函数有两种情况,没有参数时返回当前的输出格式状态,有 fmtflags类型变量做参数时,就恢复到这个参数标识的状态。
例子:ios_base::fmtflags fmtOriginal=cout.flags();
这将保存当前的状态。
cout.flags(fmtOriginal);
这将恢复到以前的状态。
@流的状态可以通过ios_base中的位来判断,这些位对应着函数如下
1,当输入流遇到文件尾时,eofbit将被设置,当流试图越过末尾提取数据时,可以调用成员函数eof来判断是否到了末尾。
cin.eof();
2,遇到文件末尾时返回true,否则false
3,当发生格式错误时候failbit将被设置
对应函数为fail()
4,当发生数据丢失错误时badbit将被设置
对应函数bad()
5,如果eof,bad,fail位都没有被设置,则goodbit被设置,表示读取正常
6, 函数rdstate返回流的错误状态,例如可以通过rdstate()读取状态,然后用switch语句检测各个位的状态
7,首选使用对应函数检测,不需要了解各个位的位置。
8, clear成员函数将重置状态为好的
例如cin.clear()清空了cin,并且将该流设置goodbit位
cin.clear(ios::failbit);将设置failbit位
9,如果badbit或者failbit被设置,则ios的成员函数operator!将会返回true,而operator void*将会返回false,这些在文件处理中很有用。