Are there any guarantees with unget?
Considering the following:
char c;
cin >> c;
cin.unget();
Assuming the char input was successful, is unget guaranteed to be able to back up at least that one character? If I ask for, and successfully get a string, can I be guaranteed to be allowed to call unget all 开发者_开发知识库the way to the beginning of that string?
You are guaranteed to be able to unget
at least 1 character. Any more than one is up to the implementation and circumstances, so you shouldn't assume that you can unget
more than one.
EDIT: Sorry I was thinking of libc's int unget(int ch, FILE *stream)
. Which the standard says:
One character of pushback is guaranteed. If the ungetc function is called too many times on the same stream without an intervening read or file positioning operation on that stream, the operation may fail.
I will see if I can find exactly what is said about basic_istream<>& unget()
EDIT: OK, so here's what the c++ standard says about basic_istream<>& unget()
(bolding added by me):
Behaves as an unformatted input function (as described in 27.6.1.3, paragraph 1). After constructing a
sentry
object, if!good()
callssetstate(failbit)
which may throw an exception, and return. Ifrdbuf()
is not null, callsrdbuf()->sungetc()
. Ifrdbuf()
is null, or ifsungetc()
returnstraits::eof()
, callssetstate(badbit)
(which may throwios_base::failure
(27.4.4.3)).
So the important bit is that it calls sungetc()
, so let's see what the standard says about that:
If the input sequence putback position is not available, returns
pbackfail()
. Otherwise, decrements the next pointer for the input sequence and returnstraits::to_int_type(*gptr())
.
I see nothing that explicitly states a limitation, so it's worth a try. If I understand this correctly, it will adjust pointers in the backing stream buffer. So as long as there is enough "history" in the buffer, it should continue to succeed.
Unlike C, however, it seems that you are never guaranteed that it will work, but you will likely be able to putback more than one character.
So my advice is to not depend on putting back more than one character, and always check for failure.
You should consider using std::istream::peek
instead.
It allows you to check the next available character without actually getting it out of the stream. This way you won't have to put it back :)
精彩评论