一、I/O类关系
在C++不直接处理输入输出,而是通过标准库中的I/O流类来进行处理。标准库主要有下面一些类:istream,ostream,iostream,ifstream,ofstream,fstream等等。其类关系图如下:
其中istream用来处理输入流,ostream处理输出流,iostream处理输入输出流,ifstream处理文件数据输入,ofstream处理文件数据输出,fstream处理文件数据输入输出。sstream中各类主要处理读写内存中string对象。
常见的流处理对象及运算符:
- cin 一个istream对象,从标准输入读取数据
- cout 一个ostream对象,向标准输出写入数据
- cerr 一个ostream对象,用于输出程序错误信息,写入到标准错误
- >>运算符,从一个istrem对象读取输入数据
- <<运算符,向一个ostream对象写入输出数据
参考
C++标准I/O库用法
。
二、ifstream,ofstream,fstream
ifstream,ofstream,fstream这3个类都在
<fstream>
中,因此需要用到相关文件处理需要包含此头文件。fstream基本包含了前面两个的功能,下面介绍fstream的用法。创建fstream类对象的方式:
- fstream obj;创建一个未绑定的文件流
- fstream obj(“file name”);创建一个文件流,并打开文件名对应的文件
- fstream obj(“file name”,mode );与2类似,以mode模式打开
第一种方式关联文件需要利用函数open(“file name”,mode ),需要注意的是不管用哪种方式创建文件对象,若是路径下文件不存在想要自动创建相应的文件,则必须加上模式ios::out。打开模式有以下一些方式:
- ios::in 以读取方式打开文件
- ios::out 以写入方式打开文件
- ios::ate 存取指针在文件末尾
- ios::app 写入时采用追加方式
- ios::trunc 写入时抹去旧数据
- ios::binary 以二进制方式存取
对于ifstream默认模式为ios::in,ofstream默认为ios::out,fstream默认为ios::in | ios::out。注意以非app模式打开文件则指针是指向文本首部的,显示使用ios::out打开文件(只有单个out模式,不包含fstream的默认情形),文件内容会被丢弃,阻止清空原数据的方法是使用app模式。
//o=流对象创建
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
fstream fp;
fstream fp1("test1.txt");
fp.open("test.txt", ios::out | ios::app );
if(!fp)
cout << "open the file erro-fp" << endl;
fp << "hello";
fp.close();
char *str = new char[10];
if(!fp1)
cout << "open the file erro-fp1" << endl;
fp1>>str; //从文件输出
cout << str;
fp1.close();
}
文件的读写
文件流进行文件的读写可以和cin,cout类似的方式进行,即利用重载的运算符<< ,>>进行文件的输出和读取。也可以用函数get(),getline(),read(),write()等。
具体应用参考:
http://blog.csdn.net/jackyxwr/article/details/4870632
二、标准输入输出流
cin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出流的对象,也是ostream 类的对象。这里的标准输出指的是终端键盘,标准错误输出指的是终端的屏幕。
cout语句的一般格式为:
cout<<表达式1<<表达式2<<……<<表达式n;
cin语句的一般格式为:
cin>>变量1>>变量2>>……>>变量n;
在定义流对象时,系统会在内存中开辟一段缓冲区,用来暂存输入输出流的数据。在执行cout语句时,先把插入的数据顺序存放在输出缓冲区中,直到输出缓冲区满或遇到cout语句中的endl(或’\n’,ends,flush)为止,此时将缓冲区中已有的数据一起输出,并清空缓冲区。输出流中的数据在系统默认的设备(一般为显示器)输出。cout通过使用头文件iomanip中定义的函数可以实现输出格式控制,常见的函数有:
setprecision(n) 设置实数的精度为n位
setw(n) 设置字段宽度为n位
setfill(c) 设置填充宇符c
setiosflags() 设置输出格式状态,括号中应给出格式状态,内容与控制符setiosflags括号中的内容相同
resetioflags() 终止已设置的输出格式状态,在括号中应指定内容
格式控制状态参考
C++格式化输出,C++输出格式控制
。
cin相对于cout使用更为复杂,下面分别介绍各用法。
1、cin>>的用法
例:cin>>a>>b; //输入两个值a,b
cin可以连续从键盘读取想要的数据,以空格、tab或换行作为分隔符,当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理。 例中a,b可以是数字,可以是字符,cin根据其数据类型分配缓冲区空间。
2、cin.get()
可以读取一个字符,也可以读取多个字符:
例:ch=cin.get(); //或者cin.get(ch);读取一个字符ch
cin.get(char*s int m); // 从缓冲区读取m个字符到s中
cin.get()从输入缓冲区读取单个字符时不忽略分隔符,直接将其读取,,读取一行时,遇到换行符时结束读取,但是不对换行符进行处理,换行符仍然残留在输入缓冲区,cin>>也是这样,因此用了cin>>之后再用getline之前最好使用syns()清空缓冲区,否则getline()会首先读到一个空字符串。
3、cin.getline()
读取一行字符,与cin.get(cha*s int m)相同,区别在于cin.getline不会将结束符或者换行符残留在输入缓冲区中,即使输入的字符大于m,s的最后一个字符也是换行符’\n’,多出的字符将放在缓冲区,但此时cin的输入标志将关闭,只有经过clear()才能使cin能够继续读数据。
cin.getline(a,4); //a为数组名或指针,须提前分配空间
cout << a <<endl;
cin.clear();
cin.getline(b,6);
//当第一次cin输入的字符大于4时,必须调用clear(),否则b无法输入,程序将直接退出
4、getline() // 接受一个字符串,可以接收空格并输出
#include<string> //包含头文件
string s;
getline(cin,s);
getline(cin,s,';');以字符';'为界读取一行数据,';'可以为任意字符
//getline读取一行字符时,默认遇到’\n’时终止,并且将’\n’直接从输入缓冲区中删除掉,
//不会影响下面的输入处理
5、gets()
gets是C中的库函数,在< stdio.h>申明,从标准输入设备读字符串,可以无限读取,不会判断上限,以回车结束或者EOF时停止读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。
char s[5];
gets(s);
//不要char*p,然后gets(p),这是错误的,因为p没有指向有效的内存,
//它可能指向任何非法地址,除非为p分配空间
6、getchar()
从stdio流中读字符,相当于getc(stdin),它从标准输入里读取下一个字符。返回类型为int型,出错返回-1。
int c;
c = getchar();
参考:
C++中cin的详细用法
7、清空输入缓冲区问题
一共有3个函数:clear(),ignore(),sync()
其中clear一般在输入出错时重新设置cin的状态,ingore()清除缓冲区字符,默认清除一个,cin.sync()的作用是清除输入缓冲区全部的内容(让流与其对应的数据源同步,这样流就可以丢弃掉之前没有处理的数据)。
参考:
cin的用法及清空输入缓冲区问题