标准输入输出
标准输入输出流
-
cin 标准输入
-
cout 标准输出
-
cerr 标注错误
-
流的四种状态
goodbit 有效状态,只有流有效时,才能正常使用
badbit 表示系统级别的错误
eofbit 表示到达了流的末尾
fialbit 表示发生了错误
bool bad() const; //若流的badbit置位,则返回true;否则返回false bool fail() const; //若流的failbit或badbit置位,则返回true;
bool eof() const; //若流的eofbit置位,则返回true;
bool good() const; //若流处于有效状态,则返回true;
extern istream cin; /// Linked to standard input
extern ostream cout; /// Linked to standard output
extern ostream cerr; /// Linked to standard error (unbuffered)
extern ostream clog; /// Linked to standard error (buffered)
在使用流的过程中要时刻注意流的状态,防止发生流失效的情况。
-
源码里面是用枚举表示的
重置流的状态
1、调用clear方法,进行重置
//clear的无参版本会复位所有错误标志位*(重置流的状态)
void clear(std::ios_base::iostate state = std::ios_base::goodbit);
2、清空缓冲区
//读取到前count个字符或在读这count个字符进程中遇到delim字符就停止,并把读取的这些东西丢掉
istream & ignore(std::streamsize count = 1, int_type delim = Traits::eof());
void test1(){
int number=-1;
//通过终端获取一个整形数据
while(cin>>number,!cin.eof())//表示没有读到流的末尾的时候
{
if(cin.bad()){
cout<<"cin had broken!"<<endl;//表示错误
return ;
}else if(cin.fail()){
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');\
//ignore的使用
cout<<"pls input a valid integer:"<<endl;;
}else{
cout<<"number:"<<number<<endl;
}
}
缓冲区
/*
此缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。
*/
缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲。
-
全缓冲:在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。
-
行缓冲:在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。
-
不带缓冲:也就是不进行缓冲,标准出错情况cerr/stderr是典型代表,这使得出错信息可以直接尽快地显示出来
//当字节数大于1024个字节时,通过cout输出的数据会立刻显示在终端上,不需要再等待三秒
void test0(){
for(int i=0;i<1025;i++){
cout<<'a';
}
sleep(3);
}
文件模式
in: 输入,文件将允许做读操作;如果文件不存在,打开失败
out: 输出,文件将允许做写操作;如果文件不存在,则直接创建一个
app: 追加,写入将始终发生在文件的末尾
ate: 末尾,读操作始终发生在文件的末尾
trunc: 截断,如果打开的文件存在,其内容将被丢弃,其大小被截断为零
binary: 二进制,读取或写入文件的数据为二进制形式
//文件输入流ifstream的使用
/*
ifstream();
explicit ifstream(const char *filename, openmode mode = in);
explicit ifstream(const string &filename, openmode mode = in);
*/
void test0(){
ifstream ifs("test.txt");//打开该文件
if(!ifs.good()){
cout<<"ifstream open file error"<<endl;
return;
}
string word;
ifs >>word;
cout<<word;
ifs.close();//关闭文件流
}
void test0(){
ifstream ifs("clog.cc");//打开该文件
if(!ifs){
cout<<"ifstream open file error"<<endl;
return;
}
//方式二:使用成员函数getline来完成
char buff[1000]={0};
while(ifs.getline(buff,1000)){
cout<<buff<<endl;
}
ifs.close();//关闭文件流
}
//读取一整个文件
void test2(){
ifstream ifs;
ifs.open("clog.cc");//第二种打开文件的方式
if(!ifs){
cout<<"ifstream open file error"<<endl;
return ;
}
//获取文件长度
int pos=ifs.tellg();//获取文件指针位置
cout<<"pos:"<<pos<<endl;
//偏移文件指针到末尾
//std::ios::cur
//std::ios::beg
//std::ios::end
ifs.seekg(0,std::ios::end);//注意第二个参数
pos=ifs.tellg(); //1、读取长短
cout<<"pos:"<<pos<<endl;
ifs.seekg(0);//回到开头 2、回到开头
char *pdata=new char [pos]();
ifs.read(pdata,pos);
string file(pdata,pos);//3、读取
cout<<file;
cout<<endl;
}
///写入一整个文件
void test1(){
std::string filename="test.txt";//当文件不存在的时候直接创造文件,如果文件存在会先清空文件中的内容,之后再进行写入
ofstream ofs(filename);
if(!ofs.good()){
cout<<"ofstream open file error"<<endl;
return ;
}
std::string line("this is a new line");
ofs<<line;
ofs.close();
}
//从后面开始写入
void test1(){
std::string filename="test.txt";//当文件不存在的时候直接创造文件
ofstream ofs(filename,std::ios::out|std::ios::app);
//app模式可以保证每一次写入文件的操作都是在文件的末尾添加数据
if(!ofs.good()){
cout<<"ofstream open file error"<<endl;
return ;
}
//输出流定位函数的名字与输入流的最后一个字母是不同的
int pos=ofs.tellp();
cout<<