iostream头文件
定义了用于读写流的基本类型fstream头文件
定义了读写命名文件的类型sstream头文件
定义了读写内存string对象的类型istream & test(istream & is)
{
int v;
while(is>>v,!is.eof()){ //遇到文件结束符终止
if(is.bad()) //若流的badbit置位,则返回true
throw runtime_error("IO流错误");
if(is.fail()){//若流的badbit或者failbit位置位,则返回true
cerr<<"数据错误,请重载: "<<endl;
is.clear(); //将流的所有条件状态位复位
is.ignore(100,'\n');
continue;
}
cout<<v<<endl;
}
is.clear();
return is;
}
int main()
{
cout<<"请输入一些整数,按Ctrl+Z结束"<<endl;
test(cin);
return 0;
}
eofbit
已到达文件尾failbit
非致命的输入/输出错误,可挽回badbit
致命的输入/输出错误,无法挽回bool bad();
bool eof();
bool fail();
bool good();
原文链接:https://blog.csdn.net/wangfutao01/article/details/6469734
#include
using namespace std;
int main()
{
cout << "hello" << endl;
cout << cout.rdstate() << endl;//输出当前的流状态:0
if(cout.rdstate() == ios::goodbit)
{
cout<<"输出数据的类型正确,无错误!"<<endl; //输出
}
if(cout.rdstate() == ios_base::failbit)
{
cout<<"输出数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
}
system("pause");
return 0;
}
//由此可知,rdstate() 返回的是eofbit,failbit,badbit三个标志的值,即返回的是一个strm::iostate类型。
方法二:我们可以用三个标志位对应的函数来测试当前的流状态。
#include
using namespace std;
int main()
{
cout << "你好吗?" << endl;
cout << cout.eof() << cout.fail() << cout.bad() << endl;
cout << cout.good() << endl;
return 0;
/*
* 你好吗?
000
1
*/
}
//我们可以用三个标志位对应的函数来测试当前的流状态。
方法三:用流本身来测试
如:
if (cin)
while (cin >> word)
if语句直接检查流的状态,while语句则检测表达式的返回值,即间接的检查流状态。
include <iostream>
using namespace std;
int main()
{
int i;
cin >> i;
if (cin)
{
cout << "流状态正常" << i << endl;
}
else
{
cout << "流状态不正常" << i << endl;
}
return 0;
}
原文链接1
原文链接2
导致缓冲刷新:
endl
来显式刷新缓冲区cout<<"hi"<<endl;
cout<<"hi"<<endl;
cout<<"hi"<<ends;//输出hi和一个空字符,然后刷新缓冲区
cout << unitbuf; //所有输出操作后都会立即刷新缓冲区
//任何输出都立即刷新,无缓冲
cout << nounitbuf; //回到正常的缓冲方式
如果程序崩溃,输出缓冲区不会被刷新.当调试一个已经崩溃的程序时,需要确定那些你以为已经输出的数据确实已经刷新了
当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流。标准库将 cout 和 cin 关联在一起,因此下面语句:
cin >> ival;
导致 cout 的缓冲区被刷新。
//tie()不带参数的版本:返回指向输出流的指针(仅当本对象关联到一个输出流上时,未关联则返回NULL)
cout << cin.tie()<<endl;
//0x6fd5acc0
cout<<(&cout)<<endl;
//0x6fd5acc0
//tie()带参数的版本接受一个指向ostream的指针,将自己关联到此ostream上
ostream *old_tie = cin.tie(nullptr);
cout<<cin.tie()<<endl; //0
cin.tie(&cerr); //将自己关联到cerr,读取cin会刷新cerr而不是cout
cout<<cin.tie()<<ends; //0x6fd5aa80
cin.tie(old_tie); //重建cin和cout间的正常关联
头文件fstream定义了三个类型来支持文件IO
ifstream
从一个给定文件读取数据.ofstream
向一个给定文件写入数据fstream
可以读写给定文件特别的,我们可以用IO运算符(<<或>>)来读写文件,可以用getline从一个ifstream读取数据
ifstream in(file);
ofstream out;//输出文件流未关联到任何文件
创建文件流对象时,当提供一个文件名时,则open会自动被调用.\
ofstream out;
out.open(s);
in.close()
in.open()
当一个fstream对象离开其作用域,与之关联的文件会自动关闭,close会自动被调用
int main()
{
ifstream in("a.txt");
if(!in){
cerr<<"无法打开文件"<<endl;
return -1;
}
string line;
vector<string> words;
while(getline(in,line)){
words.push_back(line);
cout<<" --- "<< line<<ends;
}
in.close();
vector<string>::const_iterator it = words.begin();
while(it != words.end()){
cout<<*it<<endl;
++it;
}
return 0;
}
while(in>>line){ //遇见空格停止
words.push_back(line);
cout<<"++"<< line<<ends;
}
LiLi 1212121212 3434343434
xiaomi 45454545455 6767676767
using namespace std;
struct Person{
string name;
vector<string> phonenumber;
};
int main()
{
ifstream in("E:\\practise\\Clion\\untitled\\a.txt");
vector<Person> personInfo;
if(!in){
cerr<<"无法打开文件"<<endl;
return -1;
}
string line,phone;
vector<string> words;
while(getline(in,line)){ //遇见空格停止
Person person;
istringstream recordLine(line);
recordLine >> person.name;
while(recordLine>>phone)
person.phonenumber.push_back(phone);
personInfo.push_back(person);
}
vector<Person>::const_iterator its = personInfo.begin();
while(its != personInfo.end()){
cout<<its->name<<ends;
vector<string>::const_iterator it = its->phonenumber.begin();
while(it != its->phonenumber.end()){
cout<<*it<<ends;
it++;
}
cout<<endl;
++its;
}
return 0;
}
我们将一个istringstream与刚刚读取的文本行进行绑定,这样就可以课istringstream上使用输入运算符来读取当前记录中的每个元素.