c++ IO由stream 完成,所谓的输入输出,就是字符流入stream和字符流出stream的过程,其中最重要的莫过于
istream定义input stream,用来读取数据
ostream定义output stream,用来写数据
IOStram定义了数个istream和ostream全局对象,对应标准IO的3个通道
在linux中的文件描述符为
0 : stdin : cin
1 : stdout : cout
2 : stderr : cerr, clog
Manipulator
操作符 | class | 意义 |
---|---|---|
endl | ostream | 输出\n并刷新 |
ends | ostream | 输出\0并刷新 |
flush | ostream | 刷新 |
ws | istream | 跳过空白字符 |
<<
basic_ostream将<<
定义为output操作符,对所有内建类型进行了重载,除了null和nullptr_t,但是包括char 和 void
得益于其拓展性,因此我们可以对自定义类型进行重载,这样就可以保证对任意类型都会推断出正确的打印函数
如
1 | struct test { |
要注意的是,重载的<<
运算符必须是全局的,因此对于要输出private
成员的class
我们需要设置friend
属性
>> & <<
>>
被定义成input运算符
<<
被定义成output运算符
可以从方向判断数据的流向
例如
1 | std::cout << "hello"; //流入cout缓冲区 |
Stream State(flag)
常量 | 意义 |
---|---|
goodbit | 一切都好,没有任何其他bit被设置 |
eofbit | 遇到end-of-file |
failbit | 错误,某个IO未完成,例如输入int但却混杂了一个char(格式错误) |
badbit | 毁灭性错误,例如文件指针设置错误导致的读写失败 |
字母在输入的时候并不会隐式转换为整形,以下是测试代码
1 |
|
Handle Stream State
函数 | 意义 |
---|---|
good() | 返回goodbit |
eof() | 返回eofbit |
fail() | 返回failbit或者badbit |
bad() | 返回badbit |
rdstate() | 返回当前设置的所有flag |
clear() | 清除所有flag |
clear(state) | 清除所有flag并设置state |
setstate(state) | 设置state flag |
Stream Boolean
成员函数 | 意义 |
---|---|
operator bool |
Stream是否已经出错,!fail() |
operator ! |
stream是否已经出错,fail() |
Input function
int istream::get()
读取一个字符
返回读取的字符或者EOF
istream& istream::get (char& c)
把下一个字符赋值给c
通过返回stream可以判断是否读取成功
istream& get(char *, streamsize)
终止条件是下一个字符是换行符,但不会将其读取,还会保留在缓冲区中
1 | basic_istream & |
以下代码,除了第一个std::cin.get()起作用,其他的都是直接读取缓冲区的\n
1 |
|
原因在于遇到\n
就结束,但是并不从缓冲区中把\n
取走
因此接下来的每次读取都会遇到残留在输入缓冲区里面的\n
所以要想办法
- 把
\n
取走,例如,加入std::get()
取走\n
- 直接清空缓冲区,
std::cin.ignore()
istream& istream::get(char* str, streamsize count, char delim)
- 读取的字符序列以null结尾
- 不会读取终止符delim
istream& istream::getline(char* str, streamsize count)
istream& istream::getline(char* str, streamsize count, char delim)
- 会读取结束字符 delim(
\n
) - 但是
str
不会存储结束字符
其余与get一样