What guarantees are there on interleaved reads and writes?
When working with a C++ std::iostream
(for example, std::fstream
or std::stringstream
, does the standard guarantee anything about the relationships between reads and writes performed on the same stream? That is, is it necessarily true that if I write data into a std::fstream
, then try reading data out of that stream, I should see the data I've written? How about for a std::stringstream
? As an example, is th开发者_如何学编程is guaranteed to work?
std::stringstream myStream;
myStream << "137 Hello 2.71828";
int myInt;
std::string myString;
double myDouble;
myStream >> myInt >> myString >> myDouble; // Parse as expected?
Or what about this case?
std::fstream myStream("some-file.txt", ios::in | ios::out);
myStream << "137 Hello 2.71828";
int myInt;
std::string myString;
double myDouble;
myStream >> myInt >> myString >> myDouble; // Parse as expected?
I'm asking because I recently developed a networked stream class in which reads and writes do not affect one another (since reads pull from the network and writes send across the network). That is, writing
myNetworkStream << "Hi there!" << endl;
writes across the network, while
myNetworkStream >> myValue;
reads from the network. I'm not sure that this behavior is consistent with the general contract for streams. If I had to guess, one of the following three probably holds:
- The
iostream
contract says nothing about interleaved reads and writes, or - In general the
iostream
contract says nothing about interleaved reads and writes, but there are specific previsions in the spec governing how standard types likefstream
andstringstream
work, or - The
iostream
contract does say something about interleaved reads and writes that makes my network stream class violates.
I have a copy of the spec but the section on streams is so dense and cryptic it's all but impossible to follow. If anyone could clarify exactly how iostream
s are supposed to behave when you mix reads and writes, I'd really appreciate it.
I am not sure about the chapter and verse of the C++ standard (which I don't have around to check), but I am very familiar with the C standard on the subject (which I do have around).
C99 states that a stream can be opened in read, write, or "update" mode. Only the latter mode allows both reading and writing to the same stream, but (quote):
...output shall not be directly followed by input without an intervening call to the
fflush
function or to a file positioning function (fseek
,fsetpos
, orrewind
), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.
I would assume the C++ standard says something similar somewhere: You have to flush or reposition the stream before "reversing" on the read/write direction.
Edit: Indeed there are two seperate pointers - which can be queried with basic_istream::tellg
and basic_ostream::tellp
. However, I found mention of the possibility of the two not pointing at the same position in the stream only in connection with stringstream
, not for fstream
. Taken together with the above statement, it makes sense that way. Still cannot point you to chapter and verse of the standard, though, sorry.
精彩评论