I0库类型和头文件 | ||
---|---|---|
头文件 | 类型 | |
iostream | istream,wistream从流读取数据ostream,wostream向流写入数据iostream,wiostream读写流 | |
fstream | ifstream,wifstream从文件读取数据ofstream,wofstream向文件写入数据fstream,wfstream读写文件 | |
sstream | istringstream,wistringstream从string读取数据ostringstream,wostringstream向string写入数据stringstream,wstringstream读写string | |
IO类型间的继承关系
#include <fstream>
int main()
{
ofstream out1, out2;
out1 = out2; //错误,不能对流对象赋值
ofstream print(ofstream); //错误,不能初始化ofstream
out2 = print(out2); //错误,不能拷贝对象
return 0;
}
IO操作使用时也会发生错误:
#include <iostream>using namespace std;int main(){int ival;//如果输入成功执行循环 while (std::cin >> ival) {std::cout << "cin success..." << std::endl; }return 0;}
流标志位(iostate、badbit、failbit、eofbit、goodbit)
void process_unput(istream& is){//在其中对is操作}int main(){auto old_state = cin.rdstate(); //记住cin的当前状态cin.clear(); //使cin有效(清除(复位)所有错误标志位)process_unput(cin); //使用cincin.setstate(old_state); //将cin置为原有状态return 0;}
//复位failbit和badbit,保持其他标志位不变cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
缓冲区
std::cout << "hi!" << endl; //输出hi和一个换行,然后刷新缓冲区std::cout << "hi!" << flush; //输出hi,然后刷新缓冲区,不附加任何额外字符std::cout << "hi!" << ends; //输出hi,和一个空字符,然后刷新缓冲区
std::cout << unitbuf; //后面所有的输出操作都会立即刷新缓冲区//任何输出都立即刷新,无缓冲std::cout << nounitbuf; //回到正常的缓冲方式
int ival;std::cin >> ival; //会刷新前面的输出缓冲区
cin.tie(&cout); //仅仅是用来展示:标准库将cin和cout关联在一起ostream *old_tie = cin.tie(nullptr); //cin不再与其他六关联cin.tie(&cerr); //读取cin会刷新cerr而不是coutcin.tie(old_tie); //重建cin和cout间的正常关联
iostream库
标准输入输出对象(cin、cout、cerr、clog)
std::cout << "HelloWolrd" << std::endl;
IO运算符
fstream库
ifstream in(ifile); //构造一个ifstream并打开(open)给定文件。ifile为一个文件名ofstream out; //输出文件流,未关联到任何文件
struct Sales_data {std::string isbn()const { return bookNo; }Sales_data& conbine(const Sales_data&);double avg_price()const;std::string bookNo; //图书编号unsigned units_sold = 0;//销量double revenue = 0.0; //收入};istream &read(istream &is, Sales_data &item){double price = 0; //单价//从istream对象中读取数据,将读取的内容输入到item对象中is >> item.bookNo >> item.units_sold >> price;item.revenue = price*item.units_sold;//设定item对象的收入return is;}ostream &print(ostream &os, const Sales_data &item){//将item对象的内容输出对ostream对象中os << item.isbn() << " " << item.units_sold << " "<< item.revenue << " " << item.avg_price();return os;}
int main(int argc,char *argv[]){ifstream input(argv[1]); //打开销售记录文件ofstream output(argv[2]); //打开输出文件,保存结果Sales_data total; //保存销售总额的变量if (read(input, total)) { //如果有销售记录Sales_data trans; //保存下一条销售记录的变量while (read(input, trans)) { //读取剩余记录if (total.isbn() == trans.isbn()) //如果两者编号相同,合并两者total.combine(trans); //合并并更新else {print(output, total) << endl; //如果不一样,就打印结果total = trans; //处理下一本书}}print(output, total) << endl;}else { //没有销售记录cerr << "No data?!" << endl;}return 0;}
string ifile("file_test"); //文件名ifstream in(ifile); //创建一个ifstream对象并打开给定文件ofstream out; //创建一个ofstream对象,未与任何文件关联out.open(ifile + ".copy"); //显式打开一个文件
string ifile("1.txt");ofstream out;out.open(ifile + ".copy");if(out){//...}
string ifile("1.txt");ofstream out;out.open(ifile + ".copy");if(out){//...}out.close(); //关闭out.open(ifile + "2"); //打开别的文件
//遍历参数列表for (auto p = argv + 1; p != argv + argc; ++p){ifstream input(*p); //创建一个输出流if (input) //如果创建成功process(input); //调用自定义函数对input进行操作elsecerr << "couldn't open: " + string(*p);}
文件模式 | |
---|---|
in | 以读方式打开 |
out | 以写方式打开 |
apP | 每次写操作前均定位到文件末尾 |
ate | 打开文件后立即定位到文件末尾 |
trunc | 截断文件 |
binary | 以二进制方式进行I0 |
sstream库
struct PersonInfo {std::string name; //姓名vector<std::string> phones; //电话号码};
#include <iostream>#include <string>#include <sstream>#include <vector>using namespace std;struct PersonInfo {std::string name;std::vector<std::string> phones;};int main(){std::string line, word; //line保存一行数据,word保存单个字符串std::vector<PersonInfo> people; //用来保存所有人员的信息//读取一行数据,并将整行数据保存在line中while (std::getline(std::cin, line)){PersonInfo info; //保存单条记录std::istringstream record(line); //将记录绑定到刚才输入的整行数据上record >> info.name; //根据空格,保存整行数据中的第一个字符串(人名)while (record >> word) //循环遍历,根据空格来进行分割,保存后面的号码info.phones.push_back(word); //保存号码people.push_back(info);}return 0;}
int main(){//遍历所有的人员信息,entry为const vector<PersonInfo>&类型for (const auto &entry : people){std::ostringstream formatted, badNums;//遍历所有的电话号码,nums类型为const string&for (const auto &nums : entry.phones){if (!valid(nums)) //如果号码格式无效,将错误的号码保存在badNums中badNums << " " << nums;else //如果号码格式有效,将号码保存格式化之后保存在formatted中formatted << " " << format(nums);}//如果没有错误的号码,打印if (badNums.str().empty())std::cout << entry.name << " " << formatted << " " << std::endl;//打印名字和错误的号码elsestd::cerr << "input error: " << entry.name << " invalid number(s) " << badNums.str() << std::endl;}return 0;}