[C++ Primer] 第8章: IO库

时间:2024-11-15 00:04:51

IO类

iostream定义了读写流的基本类型
istream, wistream 从流读取数据
ostream, wostream 向流写入数据
iostream, wiostream 读写流
fstream定义了读写命名文件的类型
ifstream, wifstream 从文件读取数据
ofstream, wofstream 向文件写入数据
fstream, wfstream 读写文件
sstream定义了读写内存string对象的类型
istringstream, wistringstream 从string读取数据
ostringstream, wostringstream 向string写入数据
stringstream, wstringstream 读写string

fstream和sstream继承自iostream, 这意味着接受一个iostream类型引用(或指针)参数的函数, 可以用一个对应的fstream或sstream类型来调用.

IO对象无拷贝或赋值. 进行IO操作的函数通常以引用方式传递和返回流. 读写一个IO对象会改变其状态, 因此传递和返回的引用不能是const的.

刷新输出缓冲区: endl, flush, ends.

  • endl: 输出缓冲区和一个换行, 然后刷新缓冲区.
  • flush: 输出缓冲区,然后刷新缓冲区.
  • ends: 输出缓冲区和一个空字符, 然后刷新缓冲区.

如果程序异常终止, 输出缓冲区是不会被刷新的.

文件输入输出

fstream特有的操作:
fstream fstrm; 创建一个未绑定的文件流.
fstream fstrm(s); 创建一个fstream, 并打开名为s的文件. s可以是string类型, 或者是一个指向C风格字符串的指针. 这些构造函数是explicit的.
fstream fstrm(s, mode); 以指定的方式打开.
fstrm.open(s); 打开名为s的文件.
fstrm.close(); 关闭与fstrm绑定的流.
fstrm.is_open() 返回一个bool值指出与fstrm绑定的流是否成功打开且尚未关闭.
mode模式有:
in 以读方式打开
out 以写方式打开, 会丢弃已有数据
app 向文件末尾添加
ate 打开文件后立即定位到末尾
trunc 截断文件
binary 以二进制方式打开
// 拷贝文本文件infile.txt内容到outfile.txt
int main()
{
ifstream input("infile.txt"); // 构造一个ifstream并打开给定的文件
ofstream output; // 输出文件流未关联到任何文件
output.open("outfile.txt"); // 打开指定的文件, 文件名可以值C-style字符串, 也可以是string对象(C++11标准) string line;
while(getline(input, line))
{
output << line << endl;
} input.close(); // 当一个fstream对象被销毁时, close会自动调用, 也可以手动关闭
output.close(); return 0;
}

已out模式打开文件会丢失已有数据

保留被ofstream打开的文件中已有数据的唯一方法是显示指定app或者in模式

// file1内容会丢失
ofstream out1("file1"); // 隐含out并trunc模式(截断文件)
ofstream out2("file1", ofstream::out); // 隐含trunc
ofstream out3("file1", ofstream::out | ofstream::trunc);
// file2内容不会丢失
ofstream out4("file2", ofstream::app); // 隐含out模式
ofstream out5("file2", ofstream::out | ofstream::app);

与ifstream关联的文件默认已in模式打开, 与ofstream关联的文件默认以out模式打开, 与fstream关联的文件默认已in和out模式打开.

string流

stringstream 特有操作
sstream strm 创建一个未绑定的sstream对象
sstream strm(s) strm是一个stream对象, 保存string s的一个拷贝. 此构造函数是explicit的.
strm.str() 返回strm所保存的string的拷贝
strm.str(s) 将string s拷贝到strm中.

处理行内单词的个数时, 通常可以使用istringstream.

int main()
{
string in_str("Hello World!"), str;
vector<string> svec;
istringstream iss; // 未绑定的对象
iss.str(in_str);
// istringstream iss(in_str); // 与上面两行等价 while(iss >> str)
svec.push_back(str); // 将每个单词存放到svec中 return 0;
}

当我们想逐步构造, 希望最后一起打印时, ostringstream是很有用的.

int main()
{
ostringstream oss;
// ... 省略若干行
oss << "aaa ";
// ... 省略若干行
oss << "bbbb "; cout << oss.str() << endl;
return 0;
}