C++ Primer之IO库
学习C++ Primer IO库
IO库类型及头文件:iostream(istream、ostream、iostream)、fstream(ifstream、ofstream、fstream)、sstream(istringstream、ostringstream、stringstream)
IO对象无拷贝或者赋值
ofstream os(path);//对 ofstream os1; os1=os;//错,不能赋值 ofstream os2(os1);//错,不能初始化
读写一个io对象,会改变其状态,因此传递或者返回的对象必须是引用,且不能是const.
IO的一些条件状态(C++ primer 279)。
/* 练习8.1 */ istream& printOut(istream& is){ auto old_state=is.rdstate(); is.seekg(0,ios::end); long len=is.tellg(); is.seekg(0,ios::beg); char* data=(char*)malloc(len); is>>data; cout<<data;
free(data) is.clear(); is.setstate(old_state); return is; }
关联输入和输出流
当一个输入流关联到任何一个输出流的时候,任何试图去操作输入流的数据时,都会先刷新关联的输出流。标准库将cout和cin关联在一起,因此
cin>>val;会刷新cout的缓冲区.
tie函数有两个重载版本,一个是不带参数的tie(),如果本对象没有关联到任何一个输出流的对象时,返回的是一个空指针,否则返回的是关联的输出流指针.
带参数的tie(iostream*),传递一个ostream的指针,将本对象与传递的ostream对象相关联.
ostream os*=cin.tie(nullptr);//cin不再与其他流关联 cin.tie(&cerr);//cin与cerr关联 cin.tie(os);//cin与cout重新关联
文件的输入与输出
ifstream in(path);//创建一个文件输入流并打开path路径下的文件 ofstream out;//输入流未关联到文件 /* 读取path路径下的文件; */ ifstream in;//构造一个文件输入流 in.open(path,ios::in);//以读取模式打开指定路径下的文件,如果并未指定打开的模式,那么将以默认的模式打开,ifstream默认的模式就是读取模式 string data; in>>data;//将in流中的数据出入到data中 in.close();//关闭in流 /* 写出路径为path的文件 */ ofstream out(path); string data="Hello C++"; out<<data; out.close();
注意: 当文件流是以out模式打开的时候,如果原文件本身存在,那么会先清空文件原来的数据,然后重新写入新的数据,如果不想清空原来的数据,那么可以以app模式打开文件
ofstream out(path,ios::app);//会直接在文件末尾添加新的内容
ofstream out(path,ios::ate);//打开文件会直接定位到文件末尾
我们要养成检查流的状态,然后再进行下一步操作的习惯
eg: if(out) or while(out){
//........
}
/* 8.4练习 */ void lineVec(string path){ ifstream is(path); vector<char*> vecStr; char line[1024]; while (is.getline(line,sizeof(line))) { vecStr.push_back(line); } is.close(); } /* 8.5练习 */ void charVec(string path){ ifstream is(path); vector<char> charVec; char little; while(is.get(little)) charVec.push_back(little); for (auto c:charVec) { cout<<c; } is.close(); }
string流
/*
phone.txt的内容
wade 12331231 123123123
kobe 2131 123123 123123
james 87713 2323 1231278
*/
char line[1024]; char word[1024]; vector<PersonInfo> persons; ifstream is("/Users/jy/Downloads/phone.txt",ios::in); while (is.getline(line, 1024)) { PersonInfo info; istringstream ss(line); ss>>info.name; while (ss>>word) { info.phones.push_back(word); } persons.push_back(info); }
我们常用的处理字符串的流为:sstream(istringstream,ostringstream),上面的例子,存在的疑问就是ss>>info.nam,为什么只把一行的名字输入进info.name,而不是整行的数据,下面的while(ss>>word),输入word只是后面的数字,而不是整行的内容??
/* 假定valid()是校验手机号码格式是否正确的函数,format()是格式化字符串的函数 ostringstream用法 */ for(auto const& entry:persons){ ostringstream badnums,formatted;//每一步循环创建一个输出格式不正确,和格式化的字符串输出流 for(auto& const phone:entry.phones){ if(!valid(phone)){ badnums<<phone; }else{ formatted<<phone; } } if(badnums.str().empty()){ os<<entry.name<<" "<<formatted.str()<<endl; }else{ cerr<<"error phone:"<<entry.name<<""<<badnums.str()<<endl; } }

浙公网安备 33010602011771号