C++ 中 sync_with_stdio 的作用

作者: , 共 741 字 , 共阅读 0

在实现C++中非阻塞式的用户输入中发现,在没有设置in.sync_with_stdio(false)时,in.rdbuf()里面总是空的。

// in.sync_with_stdio(false);
std::cout << in.rdbuf().in_avail() << std::endl; // always 0;

这个可能是因为如果std::cinstdio同步,std::cin就没有自己的缓冲区,而是与stdin共用缓冲区。通过设置in.sync_with_stdio(false)之后,std::cin就有了自己的缓冲区,从而能通过缓冲区内容大小,判断用户是否在输入。

不过解绑之后, C++和 C 的输入输出使用不同的缓冲区,会导致输入和输出顺序无法保障。因此要么总是用std::cin/std::cout,要么总是用printf/scanf,尽量不要混用。

注:该机制可能依赖编译器和操作系统的实现。

在刷 ACM OJ 或者 leetcode 时,很多人都会在最开头添加下面代码:

static int __ = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return 0;
} ();

这个道理是类似的。通过解绑std::iosprintf/scanf的缓冲区,提升性能。cin.tie(nullptr)则是当输入输出切换时,不会刷新缓冲区,从而更进一步提升性能 —— 默认std::cin是与std::cout绑定的,所以每次操作的时候(也就是调用<<或者>>)都要调用flush刷新。

Q. E. D.

类似文章:
编程 » C++
如果我们用std::getline或者简单的std::cin >>获取用户输入,有一个问题是,它会阻塞掉整个程序,用户必须有输入后才能继续执行。如果这个输入是单独的线程,它还会阻止整个程序的退出。
编程 » C++
要在C++中运行系统命令,可以直接使用std::system函数:
编程 » C++, 智能指针
理论上而言,当 C++提供了std::unique_ptr, C++的程序就不应该出现普通指针了。所有普通指针都可以用std::unique_ptr代替,避免手动删除对象。
编程 » C++,
C++的多行宏有标准定义方式,boostfolly库都采用了这种方式:
编程 » Matlab, 编译器
现在比较新的电脑基本上都是 64 位的 CPU , Matlab 也是 64 位的版本,但 64 位的 Matlab 没有自带编译器,需另行安装编译器。下面是方法之一:
编程 » C++, C++标准库
std::tuple的原理并不复杂,但有些细节非常有意思。其中有一个是至少在gnu C++ std的实现中,std::tuple是倒序存储的:
编程 » C++, assert, 异常处理
1)在函数开始处检验传入参数的合法性
编程 » C++, 智能指针
前面已经提到std::shared_ptr有三个缺陷:
std::thread是 C++ 11 新引入的标准线程库。在同样是 C++ 11 新引入的 lambda 函数的辅助下,std::thread用起来特别方便:
编程 » C++, 异步
C++11 的标准异步库至少包含下面内容:
周末组织一群孩子家长走了三峰拉练路线,从涧沟村出发,途径罗芭地南尖、罗芭地北尖、妙儿洼茶棚、 阳台山山顶、三界碑、妙峰山山顶、回香阁,最后回到涧沟村。
编程 » django, requests, python
requests 除了 url 之外,还有 params, data 和 files 三个参数,用于和服务器后台交互。