1.IO类:
- 定义在三个独立的头文件中(iostream、fstream、sstream)
//头文件 类型
iostream istream 从流读取数据
ostream 向流写入数据
iostream 读写流
fstream ifstream 从文件读取数据
ofstream 向文件写入数据
fstream 读写文件
sstream istringstream 从string读取数据
ostringstream 向string写入数据
stringstream 读写string
//在类型前添加w代表宽字符版本
- 不能拷贝或对io对象赋值
- 进行io操作的函数通常以引用方式传递和返回流,而读写io对象会改变其状态,因此传递和返回的引用不能是const的
- 条件状态:(查询流的状态:IO库中定义的iostate类型,提供了表达流状态的完整功能
//常用的IO库条件状态
strm::badbit 用来指出流已崩溃
strm::failbit 用来指出一个IO操作失败了
strm::eofbit 用来指出流已到达了文件结束
strm::goodbit 用来指出流未处于错误状态
s.clear() 将流s中所有条件状态位复位,将流的状态设置为有效
- 管理输出缓冲:
//刷新输出缓冲区
endl 完成换行并刷新缓冲区
flush 刷新缓冲区,但不输出任何额外的字符
ends 向缓冲区插入一个空字符,并刷新缓冲区
unitbuf操纵符
cout << unitbuf; //所有输出操作后都会立即刷新缓冲区
//任何操作都立即刷新,无缓冲
cout << nounitbuf; //回到正常的缓冲方式
2.文件输入输出:
- ftream特有的操作:
fstream fstrm; //创建一个未绑定的文件流
fstream fstrm(s); //创建一个fstrem,并打开名为s的文件
fstream fstrm(s, mode); //与上一个函数类似,但按指定mode打开文件
fstrm.open(s) //打开名为s的文件,并将文件与fstrm绑定
fstrm.close() //关闭与fstrm绑定的文件
fstrm.is_open() //返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭
- 使用文件流对象:
ifstream in(file); //构造一个ifstream并打开指定文件
ofstream out; //输出文件流未关联到任何文件
- 当一个fstream对象离开其作用域时,与之关联的文件会自动关闭
- 文件模式:
in //以读方式打开
out //以写方式打开
app //每次写操作前均定位到文件末尾
ate //打开文件后立即定位到文件末尾
trunc //截断文件
binary //以二进制方式进行IO
//其中每次打开文件时都要设置文件模式,为了保存文件内容,显示指定app模式
ofstream out("file",ofstream::app); //定位到文件末尾,保存文件中的已有数据
3.string流:
- stringstream特有的操作:
sstream strm; //strm是一个未绑定的stringstream对象
sstream strm(s); //strm是一个sstream对象,保存string s的一个拷贝
strm.str() //返回strm所保存的string的拷贝
strm.str(s) //将string s拷贝到strm中
4.部分习题解答:
8.1、8.2:
#include <iostream>
#include <string>
using namespace std;
istream& func(istream &is)
{
string word;
while (is >> word)
cout << word << endl;
is.clear();
return is;
}
int main()
{
func(cin);
system("pause");
return 0;
}
8.3:
遇到文件结束符,或者遇到了IO流错位或者读入了无效数据
8.4、8.5:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc,char **argv)
{
string infile = "1.txt";//代表文件名
vector<string> vec;
ifstream in(infile);
if (in)
{
string buf;
while (getline(in,buf)) //8.5改为while (in >> buf)
{
vec.push_back(buf);
}
}
else
{
cerr << "cannot open this file " << infile << endl;
}
for (int i = 0; i < vec.size(); ++i)
{
cout << vec[i] << endl;
}
system("pause");
return 0;
}
8.6、8.7、8.8:
#include <iostream>
#include <fstream>
#include "Sales_data.h"
using namespace std;
int main(int argc, char *argv[])
{
if (argc != 2) {
cerr << "Please give the file name." << endl;
return -1;
}
ifstream in(argv[1]);
if (!in) {
cerr << "Can't open the file." << endl;
return -1;
}
Sales_data total;
if (read(in, total)) {
Sales_data trans;
while (read(in, trans)) {
if (total.isbn() == trans.isbn())
total.combine(trans);
else {
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
}
else {
cerr << " No data?!" << endl;
}
system("pause");
return 0;
}
//8.7添加如下代码,并将第一个判断改为3
ofstream out(argv[2]); //8.8将这句修改为ofstream out(argv[2],ofstream::app);
if (!out){
cerr << "can't open output file." << endl;
return -1;
}
8.9:
#include <iostream>
#include <string>
using namespace std;
istream& func(istream &is)
{
string word;
while (is >> word)
cout << word << endl;
is.clear();
return is;
}
int main()
{
ostringstream msg;
msg << "C++ Primer 5th edition" << endl;
istringstream in(msg);
func(in);
system("pause");
return 0;
}
8.10:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
ifstream in("Data.txt");
if (!in) {
cerr << " Can't open input file." << endl;
return -1;
}
string line;
vector<string> vec;
while (getline(in, line)) {
vec.push_back(line);
}
in.close();
auto it = vec.begin();
while (it != vec.end()) {
istringstream line_str(*it);
string word;
while (line_str >> word)
cout << word << endl;
++it;
}
system("pause");
return 0;
}
8.11:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
struct PersonInfo {
string name;
vector<string> phones;
};
int main()
{
string line, word;
vector<PersonInfo> people;
istringstream record;
while (getline(cin, line)) {
PersonInfo info;
record.clear();
record.str(line);
record >> info.name;
while (record >> word)
info.phones.push_back(word);
people.push_back(info);
}
system("pause");
return 0;
}
8.12:
由于每个人的电话号码数量不固定,因此更好的方式是在缺省初始化之后,在程序中设置人名并逐个添加电话号码
8.13:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
struct PersonInfo {
string name;
vector<string> phones;
};
string format(const string &s) { return s; }
bool valid(const string &s)
{
return true;
}
int main(int argc, char *argv[])
{
string line, word;
vector<PersonInfo> people;
istringstream record;
if (argc != 2) {
cerr << "Please give the file name." << endl;
return -1;
}
ifstream in(argv[1]);
if (!in)
{
cerr << "can't open input file" << endl;
return -1;
}
while (getline(in, line)) {
PersonInfo info;
record.clear();
record.str(line);
record >> info.name;
while (record >> word)
info.phones.push_back(word);
people.push_back(info);
}
ostringstream os;
for (const auto &entry : people) {
ostringstream formatted, badNums;
for (const auto &nums : entry.phones) {
if (!valid(nums)) {
badNums << " " << nums;
}
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;
}
cout << os.str() << endl;
return 0;
}
8.14:
不创建实参的拷贝,不修改其对象值