- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有人可以更明确地解释缓冲区的概念吗?我知道缓冲区是存储字符的数据结构,也是要从中读取数据的位置。刷新缓冲区的想法是什么?
当刷新缓冲区时,这是指写入存储在其中的字符的行为吗?
从文字:
To avoid the overhead of writing in response to each output request, the library uses the
buffer to accumulate the characters to be written, and flushes the buffer, by writing its
contents to the output device, only when necessary. By doing so, it can combine several
output operations into a single write.
When our program writes its prompt to cout, that output goes into the buffer associated
with the standard output stream. Next, we attempt to read from cin. This read flushes
the cout buffer, so we are assured that our user will see the prompt.
Writing the value of std::endl ends the line of
output, and then flushes the buffer, which forces the system to write to the output
stream immediately.
最佳答案
缓冲的基本思想是将操作组合成更大的块:读取整个页面而不是读取少量字节,而是根据请求使其可用;而不是写入少量字节,而是将它们缓冲起来并写入整个页面,或者在显式请求写入时写入。本质上,这是重要的性能优化。对于I/O操作来说,这很明显,但是通常也适用于其他用途:一次处理多个单元通常比处理单个单元要快。
关于I/O刷新,是指将当前缓冲的字节写入其目的地-实际上这意味着什么。对于C++ IOStreams,刷新流等于调用成员函数std::ostream::flush()
,后者又在关联的流缓冲区上调用std::streambuf::pubsync()
(这忽略了该流实际上是类模板的细节,例如std::basic_ostream<cT, traits>
;出于此讨论的目的,这无关紧要它们是类模板):基类std::streambuf
是C++关于如何处理特定流的抽象。它在概念上由输入和输出缓冲区以及分别负责读取或写入缓冲区的虚函数组成。函数std::streambuf::pubsync()
调用虚拟函数std::streambuf::sync()
,该函数应为每个可能缓冲字符的流缓冲区重写。也就是说,刷新的实际含义取决于该虚拟功能的实现方式。sync()
的覆盖是否实际起作用以及它的作用显然取决于流缓冲区表示的内容。例如,对于负责读写文件的std::filebuf
,sync()
写入缓冲区的当前内容,并从缓冲区中删除刷新的字符。鉴于文件可能并不真正代表物理文件,但例如与不同进程进行通信的命名管道,这是合理的行为。另一方面,刷新std::stringbuf
,它是用于实现对使用的std::string
进行写入的流缓冲区。 by std::ostringstream
实际上不执行任何操作:字符串完全在程序中,并且表示其值的std::string
是在调用std::stringbuf::str()
成员函数时构造的。对于用户定义的流缓冲区,有许多不同的行为。常见的一类流缓冲区是在将输出传递到另一个流缓冲区之前以某种方式过滤输出(例如,日志记录缓冲区可能会在每个换行符之后添加时间戳)。这些通常只调用下一个流缓冲区的std::streambuf::pubsync()
函数。
因此,对实际行为的描述通常含糊不清,因为尚不清楚确切会发生什么。从概念上讲,刷新流或在流缓冲区上调用pubsync()
应该更新字符的外部目标以匹配当前内部状态。通常,这相当于转发当前缓冲的字符并将其从内部缓冲区中删除。在这一点上,值得注意的是,缓冲区通常在刚满时也会被写入。它何时变满,再次取决于特定的流缓冲区。好的std::filebuf
实现实质上将填充与基础页面(或其倍数)大小匹配的字节缓冲区,然后写入完整的页面,从而最大程度地减少所需的I/O操作数量(这实际上相对棘手,因为缓冲区大小在不同的文件系统之间是不同的,并且取决于写入时产生的字节数无法轻易估算出的编码方式)。
标准C++库通常不需要显式刷新:
std::cerr
设置为自动刷新在调用每个输出操作后产生的任何输出。这是默认设置格式标志std::ios_base::unitbuf
的结果。要关闭此功能,您可以使用std::cerr << std::nounitbuf
,也可以只使用std::clog
,它会写入同一目标位置,但不会执行此刷新操作。 std::istream
读取时,将刷新“绑定(bind)的” std::ostream
(如果有)。默认情况下,std::cout
与std::cin
绑定(bind)在一起。如果您想自己设置绑定(bind)的std::ostream
,则可以使用例如in.tie(&out)
,或者,如果您想删除绑定(bind)的std::ostream
,则可以使用例如std::cin.tie(0)
。 std::ostream
被销毁时(或者在std::ostream
是标准流之一的情况下正常销毁时),会刷新std::ostream
。 std::streambuf::overflow()
,该函数通常将当前缓冲区的缓冲区(加上传递的字符,如果有的话)写入其目的地。通常,这只是通过调用sync()
清除当前缓冲区来完成的,但是具体要执行什么操作取决于具体的流缓冲区。 std::ostream
:
std::ostream::flush()
,例如std::cout.flush()
。 std::streambuf::pubsync()
,例如std::cout.rdbuf()->pubsync()
(假设已设置流缓冲区;如果没有流缓冲区,则调用std::ostream::flush()
将不执行任何操作)。 std::flush
,例如std::cout << std::flush
。 std::endl
,例如std::cout << std::endl
首先写入换行符,然后刷新流。请注意,当您确实要刷新输出时,应仅将std::endl
用作。 实际上只想创建行尾时,请勿使用std::endl
!只需为后者写一个换行符! std::cin
读取时)是通过将
std::cout
转换为
tie()
到
std::cin
来处理的。当使用其他I/O机制时,可能需要显式
tie()
相关流。如果程序在调试期间“崩溃”或断言,则缓冲区有时会成为问题,因为流的某些输出可能已完成但尚未发送。解决方法是使用
std::unitbuf
。
关于c++ - C++ cout和cin缓冲区,以及一般的缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9274057/
我想知道 cout<
这可能是一个初学者问题,了解 cout 的工作原理可能是这里的关键。如果有人可以链接到一个好的解释,那就太好了。 cout(&cout) 的地址. cout << &cout打印出 cout 的地址.
经过一整天的编码,我不小心写了 cout << "some text" << cout; 代替 cout << "some text" << endl; 现在它打印出一个内存地址。它指向什么? 最佳答
这与 difference-between-cout-x-and-cout-operator-x 有关问题,但还是有点不同... #include int main(){ std::cout
我是 C++ 的新手,最近我花了几天时间阅读有关指针的内容。我意识到下面的 2 段代码给我不同的结果,尽管它们看起来相同。 第一段代码: int a = 5; int* ptr = &a; cout
我尝试使用更短的语法并避免在任何地方使用 std::,所以我开始使用新的别名语法。在一些例子中,我看到人们这样使用它: using json = nlohmann::json; 并尝试使用 std::
这是我的头文件 #ifndef KINGDOM_H_ #define KINGDOM_H_ #include using namespace std; namespace sict{ cla
我经常遇到要将二维数组打印到屏幕或文件的情况。我的标准方法是这样的: for(int q=0; q #include void printNumber(int x) { std::cout
有一些 cout 语句,但第一个 cout 语句末尾的空格出现在第二个 cout 语句的开头。这是代码: #include int main() { using namespace std;
我在搞乱代码时遇到了这种相当模糊的行为,这是示例: #include using namespace std; int print(void); int main(void) { cout
我收到所有 cout 和 endl 的这些错误消息: main.cc:17:5: error: ‘cout’ was not declared in this scope main.cc:17:5:
这个问题在这里已经有了答案: What is the meaning of prepended double colon "::"? (9 个回答) 关闭 7 个月前。 有一个简单的代码,包含::操
我有下面的代码,我不太明白为什么结果恰好像下面这样: #include #include using namespace std; int main () { std::stringstre
在 C++ 中,当我在 .h 文件中声明自己的命名空间时,如下所示: namespace my_own { //... } 那么,如果我在命名空间 my_own 内部或外部声明 using s
背景 IIRC,来自 Release 2.0 C++ 将单字符常量存储为类型 char而不是 int .但是在 Release 2.0 之前声明如下 cout #include using name
Problem was in IDE I am using - CLion 1.2.4 gives incorrect output inside its own output window, sol
我知道有几个这样的拷贝,但到目前为止,没有一个对我有用。我正在尝试使用 g++ 在 Ubuntu 上编译一个非常简单的 C++ 程序,但它给了我范围错误。 #include using namesp
我在这里有一个难题,我无法解决,也没有在网上找到正确的答案: 我创建了一个带有清理路由的分离线程,问题是在我的 Imac 和 Ubuntu 9.1(双核)上。我无法正确取消空闲代码中的分离线程: #i
#include #include #include using namespace std; int main() { ofstream fout("test.txt"); f
我是一名优秀的程序员,十分优秀!