IO

大致分为三类,标准io,文件io,stringio。下面一张大图表示这几种io的继承方式,常用的三种io流都继承于ios基类

IO的条件状态

这些IO条件状态用于在执行IO操作时判断当前IO的状态如何从而采取相应的措施

1
2
3
4
strm::badbit // 流已崩溃
strm::failbit // IO操作失败
strm::eofbit // 用于指出已经到达流的末尾
strm::goodbit // 用于指出流末尾处于错误状态

基础IO对象的成员如下

1
2
3
4
5
6
7
8
9
strm s; // s为一个IO对象
s.eof() // 如果流的eof位置位,返回true
s.good() // 流处于有效状态返回true
s.bad() // 流badbit置位返回true
s.fail() // 流failbit位置位返回true
s.clear() // 将流的所有位复位,状态位为有效
s.clear(flags) // 指定流的特定位复位
s.setstate(flags) // 指定流的特定位置位
s.rdstate() // 返回流的当前状态,类型为ios::state

标准IO

1
2
3
4
#include <iostream>

std::istream
std::ostream

特别需要注意io对象不能复制和赋值,可以通过引用。

1
2
3
4
#include <iostream>

std::istream& user_in = std::cin; //正确,如果函数需要io参数,使用引用类型
std::istream user_in = std::cin; //错误,编译时报错

文件IO

1
2
3
4
#include <fstream>

std::ifstream;
std::ofstream;

这里一直没有搞懂的一点,用户输入和文件输入这两个的区别。用户输入指的是用户从键盘输入数据,而文件输入指的是从文件输入数据到某处。

这里有两个例子,分别是代表文件io和标准io,他们的最终目标都是一个:将数据送入buffer中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <fstream>

int main() {
char buf[256];

//标准IO输入操作
std::ifstream file_in("./example.txt");
file_in.getline(buf, 256); // 将文件内如送入数组buf中

//文件IO输入操作
std::istream& user_in = std::cin;
user_in.getline(buf, 256); // 将用户输入送入数组buf中
}

所以可以总结下什么是输入和输出。

  • 输入:不管对象如何,都是将这个对象的数据送入程序的buffer中,这种操作统称为输入。

  • 输出:不管数据来源与何处,只要将数据送入对象中,这种操作统一称为输出。

stringIO

1
2
std::istringstream
std::ostringstream

常用两个对象,操作和上面两种IO的操作方式一样,只需要介绍下特有的操作

1
2
3
4
sstream strm; // 创建一个未绑定的stringstream对象
sstream strm(str); // 将str绑定到stringstream对象
strm.str(); // 返回绑定对象的字符串
strm.str(str); // 将字符串str拷贝到strm中

文件打开方式

介绍一个名词叫做文件截断,意思就是在进行写文件的操作时,在写结束后,如果文件后面还有内容那么后面的内容全部清除,所以如果要进行写文件操作一般采用app的方式打开。

文件打开有五种方式:inoutappatetruncbinnary

如果使用out等模式打开默认是截断文件的

assert函数

assert函数定义在头文件cassert中,使用方法为

1
2
3
4
5
assert(true);
#ifndef NDEBUG
// 需要输出的错误语句
cerr << __func__ << ": string size is " << s.size() << endl;
#endif

如果在编译时添加-D NDEBUG这个选项,则#ifndef部分的语句就不会输出

常用的5个程序调试名字

  • __FILE_: 存放文件名的字符串
  • __LINE__: 存放当前行号
  • __TIME__: 存放文件编译时间
  • __DATE__: 存放文件编译日期

完整代码和测试结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cassert>

using namespace std;

int main(int argc, char* argv[]) {
string s("some string");
assert(s.size() > 0);

#ifndef NDEBUG
cerr << "__FILE__: " << __FILE__ << endl;
cerr << "__LINE__: " << __LINE__ << endl;
cerr << "__DATE__: " << __DATE__ << endl;
cerr << "__TIME__: " << __TIME__ << endl;
cerr << "__func__: " << __func__ << endl;
#endif

return 0;
}
1
2
3
4
5
__FILE__: main.cpp
__LINE__: 31
__DATE__: Mar 9 2022
__TIME__: 23:41:29
__func__: main