文章目录
- 1. 目的
- 2. I/O Streams 输入/输出流
- 3. Stream Operators 流操作符
- 4. 禁止使用 `std::endl`
- 5. 缓冲区:直观理解
- 6. References
1. 目的
查看 hackingcpp 上的 Input & Output (Basics) 教程后的笔记和拓展内容。
2. I/O Streams 输入/输出流
使用 C++ 的标准输入和输出的例子代码如下:
#include <iostream>
int main () {
int i;
// read value into i
std::cin >> i;
// print value of i
std::cout << i << '\n';
}
解释:
std::cin
是一个变量, 而不是函数。std::cout
,std::cerr
,std::clog
也是对象std::cin
意思是 “characters from stdin”, 其中 stdin 是 standard input 标准输入的缩写,std::cin
是从标准输入的缓冲(buffer)读取内容。 标准输入可以有很多种,最常见的是键盘。std::cout
意思是 “characters to stdout”, 其中 stdout 是 standard output 标准输出的缩写,std::cout
是把内容写到缓冲区(buffer), 如果缓冲区满了则输出到控制台。重定向到文件的话, 对应到的 fd 为 1。std::clog
意思是 “characters to stderr”, 其中 stderr 是 standard error 标准错误输出的缩写,std::cerr
是把内容写到缓冲区(buffer),如果缓冲区满了则输出到控制台; 这看起来和std::cout
差不多, 区别在于如果重定向到文件,std::clog
对应到的 fd 为 2。std::cerr
意思是 “characters to stderr”, 是说把内容立即写入到控制台, 而不经过“缓冲区”(buffer)。这是和std::log
的差别。std::cerr
内容重定向到文件的话, fd 也是 2.
3. Stream Operators 流操作符
>>
意思是 “get from”, 获取内容。 语法是 source >> target
.
<<
意思是 “put to”, 写入内容。 语法是 target << source
.
- 流对象的
>>
和<<
两个操作符,适用于基础类型 以及 string 类型 >>
持续读取, 直到遇到下一个空白字符(空格,tab,换行,。。。)- 可以是链式操作, 也就是说
std::cin >> xx
是有返回值的, 返回值仍然是std::cin
对象。 其他三个对象也是返回自身:
int i = 0;
double d = 0.0;
// read 2 values of different type:
std::cin >> i >> d;
// print 2 values and some text:
std::cout << "your input:\n"
<< i << " and " << d << '\n';
4. 禁止使用 std::endl
作者禁止学员们使用 std::endl
原因是每次调用 std::endl
都会刷新(flush)缓冲区, 也就是立即输出到控制台, 而频繁写到控制台基本上等于说没有缓冲区, 使得性能变慢。
std::cout << "some text" << std::endl; // bad
std::cout << "more text" << std::endl; // bad
std::cout << "some text\n" << std::endl; // ok
std::cout << "more text\n" << std::endl; // ok
5. 缓冲区:直观理解
fprintf(stderr, ...)
会直接输出到屏幕, 不会考虑缓冲区。
于是, 在 fprintf(stderr, ..)
的前面、后面分别用 print/cout 输出, 并且不含有 std::endl
, 会发现有趣的现象: 内容分布在两行:
int test2()
{
for (int i = 0; i < 10; i++)
{
std::cout << "1 ";
printf("2 ");
}
fprintf(stderr, "This is stderr output\n");
for (int i = 0; i < 10; i++)
{
std::cout << "1 ";
printf("2 ");
}
return 0;
}
输出为:
This is stderr output
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 %
也就是说, fprintf(stderr, ...)
立即写入到屏幕, 不会破坏原有的 printf / std::cout 的写入缓冲区的操作, 而缓冲区虽然大小我们不知道, 但是肯定是容纳了所有的 "1 " 和 "2 " 的输出内容, 连在了一块儿。
6. References
- C/C++ 输入输出缓冲区在Windows和Linux下对比
- https://hackingcpp.com/cpp/std/io_basics.html