缓冲和非缓冲流
在缓冲流的情况下,它在书中说它等到缓冲区已满才写回监视器.例如:
In case of buffered stream it said in a book that it wait until the buffer is full to write back to the monitor. For example:
cout << "hi";
缓冲区已满"是什么意思.
What do they mean by "the buffer is full".
cerr << "hi";
我的书上说发送到cerr
的所有东西都会立即写入标准错误设备,这是什么意思?
It is said in my book that everything sent to cerr
is written to the standard error device immediately, what does it mean?
char *ch;
cin>> ch; // I typed "hello world";
在这个例子中,ch
将被分配给hello"而world"将被忽略,这是否意味着它仍在缓冲区中并且会影响未来语句的结果?
In this example ch
will be assigned to "hello" and "world" will be ignored does it mean that it still in the buffer and it will affect the results of future statements?
推荐答案
你的书似乎不太有用.
1) 输出流将它们的字节发送到 std::streambuf
,它可能包含一个缓冲区;使用的 std::filebuf
(派生自 streambuf
)并且 std::ofstream
通常会被缓冲.这意味着当你输出一个字符,不一定立即输出;它会写入缓冲区,仅当缓冲区被写入时才输出到操作系统full,或者您以某种方式明确请求它,通常是通过调用flush()
(直接或间接,通过使用 std::endl
).然而,这可能会有所不同;std::cout
的输出与stdout
,并且大多数实现或多或少会遵循以下规则stdout
for std::cout
,如果输出要去一个交互式设备.
1) The output streams send their bytes to a std::streambuf
, which may
contain a buffer; the std::filebuf
(derived from streambuf
) used by
and std::ofstream
will generally be buffered. That means that when
you output a character, it isn't necessarily output immediately; it will
be written to a buffer, and output to the OS only when the buffer is
full, or you explicitly request it in some way, generally by calling
flush()
on the stream (directly, or indirectly, by using std::endl
).
This can vary, however; output to std::cout
is synchronized with
stdout
, and most implementations will more or less follow the rules of
stdout
for std::cout
, changing the buffering strategy if the output
is going to an interactive device.
无论如何,如果您不确定,并且您想确保输出确实离开了您的程序,只需添加对flush的调用.
At any rate, if you're unsure, and you want to be sure that the output really does leave your program, just add a call to flush.
2) 你的书在这里错了.
2) Your book is wrong here.
缓冲策略之一是unitbuf
;这是一个标志std::ostream
您可以设置或重置 (std::ios_base::set()
和std::ios_base::unset()
—std::ios_base
是std::ostream
,所以你可以在 std::ostream
上调用这些函数目的).当设置了 unitbuf
时,std::ostream
添加对 flush()
的调用到每个输出函数的末尾,所以当你写:
One of the buffering strategies is unitbuf
; this is a flag in the
std::ostream
which you can set or reset (std::ios_base::set()
and
std::ios_base::unset()
—std::ios_base
is a base class of
std::ostream
, so you can call these functions on an std::ostream
object). When unitbuf
is set, std::ostream
adds a call to flush()
to the end of every output function, so when you write:
std::cerr << "hello, world";
流将在字符串中的所有字符之后被刷新是输出,提供 unitbuf
设置.启动时,unitbuf
被设置对于 std::cerr
;默认情况下,它不会在任何其他文件上设置.但是你可以随意设置或取消设置.我会建议反对在 std::cerr
上取消设置,但如果 std::cout
输出到交互式设备,将其设置在那里很有意义.
the stream will be flushed after all of the characters in the string
are output, provided unitbuf
is set. On start-up, unitbuf
is set
for std::cerr
; by default, it is not set on any other file. But you
are free to set or unset it as you wish. I would recommend against
unsetting it on std::cerr
, but if std::cout
is outputting to an
interactive device, it makes a lot of sense to set it there.
请注意,这里的所有问题都是 streambuf
中的缓冲区.通常,操作系统也会缓冲.所有刷新缓冲区的作用是将字符传输到操作系统;这个事实意味着你不能使用ofstream
在需要事务完整性时直接使用.
Note that all that is in question here is the buffer in the streambuf
.
Typically, the OS also buffers. All flushing the buffer does is
transfer the characters to the OS; this fact means that you cannot use
ofstream
directly when transactional integrity is required.
3) 当您使用 >>
输入字符串或字符缓冲区时,std::istream
首先跳过前导空格,然后输入最多但不包括下一个空格.在正式条款中标准,它从流中提取"字符,以便它们不会再被看到(除非你寻找,如果流支持它).下一个输入将从前一个停止的地方拾取.无论以下字符在缓冲区中,或仍在磁盘上,确实是无关紧要.
3) When you input to a string or a character buffer using >>
, the
std::istream
first skips leading white space, and then inputs up to
but not including the next white space. In the formal terms of the
standard, it "extracts" the characters from the stream, so that they
will not be seen again (unless you seek, if the stream supports it).
The next input will pickup where ever the previous left off. Whether
the following characters are in a buffer, or still on disk, is really
irrelevant.
请注意,输入的缓冲有点复杂,因为它发生在几个不同的级别,在操作系统级别,它需要不同的形式取决于设备.通常,操作系统将通过以下方式缓冲文件部门,通常提前读取几个部门.操作系统将始终返回所需数量的字符,除非遇到结尾文件.大多数操作系统将逐行缓冲键盘:不从读取请求直到输入完整行,并且永不返回读取请求中超出当前行末尾的字符.
Note that the buffering of input is somewhat complex, in that it occurs at several different levels, and at the OS level, it takes different forms depending on the device. Typically, the OS will buffer a file by sectors, often reading several sectors in advance. The OS will always return as many characters as were demanded, unless it encounters end of file. Most OSs will buffer a keyboard by line: not returning from a read request until a complete line has been entered, and never returning characters beyond the end of the current line in a read request.
以与 std::ostream
相同的方式使用 streambuf
进行输出,std::istream
使用一个来获取每个单独的字符.在这种情况下std::cin
,通常是一个filebuf
;当 istream
请求一个字符,filebuf
将从它的缓冲区返回一个,如果它有一个;如果没有,它将尝试重新填充缓冲区,请求例如512 个(或任何它的缓冲区大小)字符操作系统.哪个将根据其缓冲策略做出响应设备,如上所述.
In the same manner as std::ostream
uses a streambuf
for output,
std::istream
uses one to get each individual character. In the case
of std::cin
, it will normally be a filebuf
; when the istream
requests a character, the filebuf
will return one from its buffer if
it has one; if it doesn't, it will attempt to refill the buffer,
requesting e.g. 512 (or whatever its buffer size is) characters from the
OS. Which will respond according to its buffering policy for the
device, as described above.
无论如何,如果 std::cin
连接到键盘,并且您已经输入"hello world"
,你输入的所有字符都会被读取最终由溪流.(但如果你使用 >>
,将会有很多你看不到的空白.)
At any rate, if std::cin
is connected to the keyboard, and you've
typed "hello world"
, all of the characters you've typed will be read
by the stream eventually. (But if you're using >>
, there'll be a lot
of whitespace that you won't see.)
相关文章