# include<iostream>
#include<string>
#include<fstream>
#include<vector>
using namespace std;
//io类
void test01() {
//io类包含的头文件有iostream istream ostream 用于向流中读写数据
//fstream ifstream ofstream 用于向文件中读写数据
//sstream istringstream ostringstream 用于向string中读写数据
//wcin,wcout,wcerr对应cin,cout, cerr的宽字符版对象
//io对象没有拷贝和赋值
ofstream out1, out2;
//out1 = out2; 错误 不能对流对象进行赋值操作
ofstream print(ofstream); // 不能初始化ofstream参数
//out2 = print(out2); 不能拷贝流对象
//因此我们不可以将返回值或者形参设置为流类型,进行io操作的函数通常以引用方式传递和返回流,读写一个io对象是会改变他的状态,因此传递和引用的不可以是const的
//条件状态
int ival;
cin >> ival; // 如果我们在标准输入上键入了一个BOO,这样操作就会失败,cin会进入错误状态
//因此我们在使用一个流对象前应该检验一下它是否处于良好的状态,确定一个流对象的状态最好的方法是把它当做一个条件来使用
string word;
while (cin >> word) {};
//查询流的状态
//iostate 可以上网看看文档
//管理条件状态(不懂) 书的281页
/*auto old_state = cin.rdstate();
cin.clear();
process_input(cin);
cin.setstate(old_state);*/
//管理输出缓冲
/*
导致缓冲刷新的原因:
1.程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行
2.缓冲区满时,需要刷新缓冲
3.我们可以使用endl来显示刷新缓冲区
4.在每个输出操作之后,我们可以用操作符unitbuf设置流的内部状态,来清空缓冲区,默认情况下,对cerr是设置unitbuf
5.一个输出流可以被关联到另一个流,默认情况下,cin和cerr都被关联到cout
*/
//刷新输出缓冲区和unitbuf操作符
cout << "hi" << endl; //输出hi和一个换行,然后刷新缓冲区
cout << "hi" << flush; //输出hi,然后刷新缓冲区,不附加任何额外字符
cout << "hi" << ends;//输出hi和一个空字符,然后刷新缓冲区
cout << unitbuf; //所有输出操作都会立即执行刷新缓冲区
cout << nounitbuf; //回到正常的缓冲方式
//如果程序异常终止,输出缓冲区是不会被刷新的
//关联输入输出流
cin >> ival;
cin.tie(&cout);
ostream* old_tie = cin.tie(nullptr); //cin不再与其他的流关联
cin.tie(&cerr); //将cin和cerr关联
cin.tie(old_tie); //重建cin和cout的正常关联
}
//文件输入输出
void test02() {
string ifile;
ifstream in(ifile);
ofstream out;
//文件名既可以是string对象也可以是c风格的字符数组
//文件模式
//通过tou模式打开文件会丢弃已有的数据
}
//用fstrean代替iostream&
//ifstream input(argv[1]);
//ostream 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;
//}
//自动构造和析构
for (auto p = argv + 1; p != argv + argc; ++p) {
ifstream input(*p);
if (input) {
process(input);
}
else {
cerr << "can not open " + string(*p) << endl;
}
//input是while循环的局部变量,它在每一个循环中都要创建和销毁一次。当一个fstream对象被销毁时,close会自动调用
}
//string流
//istringstream, ostringstream
struct PersonInfo {
string name;
vector<string>phones;
};
string line, word;
vector<PersonInfo>people;
while (getline(cin, line)) {
PersonInfo info;
istringstream record(line);
record >> info.name;
while (record >> word) {
info.phones.push_back(word);
}
people.push_back(info);
}
for (cont auto& entry : people) {
ostringstream formatted, badNums;
for (const auto& nums : entry.phones) {
if (!valid(nums)) {
badNums << " " << endl;
}
else {
formatted << " " << format(nums);
}
}
if (badNums.str().empty())
os << entry.name << " " << formatted.str() << endl;
else
cerr << "input error" << entry.name << "invalid number(s)" << badNums.str() << endl;
}
void test03() {
}
int main() {
test01();
test02();
system("pause");
return 0;
}