Cracking C++(10): 基本的输入输出流

文章目录

    • 1. 目的
    • 2. I/O Streams 输入/输出流
    • 3. Stream Operators 流操作符
    • 4. 禁止使用 `std::endl`
    • 5. 缓冲区:直观理解
    • 6. References

1. 目的

查看 hackingcpp 上的 Input & Output (Basics) 教程后的笔记和拓展内容。

2. I/O Streams 输入/输出流

Cracking C++(10): 基本的输入输出流_第1张图片

使用 C++ 的标准输入和输出的例子代码如下:

#include 

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 流操作符

Cracking C++(10): 基本的输入输出流_第2张图片

>> 意思是 “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

Cracking C++(10): 基本的输入输出流_第3张图片

作者禁止学员们使用 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

你可能感兴趣的:(C/C++,c++,开发语言)