std::fstream stream("filename",std::ios::in | std::ios::out | std::ios::binary); char byte; stream.read(&byte,1); // stream.seekp(1); int bytesCount = 4096; auto bytesVec = std::vector<char>(bytesCount,'c'); char* bytes = bytesVec.data(); std::cout << stream.bad() << std::endl; stream.write(bytes,bytesCount); std::cout << stream.bad() << std::endl;
如果我执行这个代码,那么第一个bad()返回false,但是第二个返回true,实际上没有写入.
如果我将bytesCount减小到小于4096的值(大概是一些内部缓冲区的大小),那么第二个bad()返回false,但仍然没有写入.
如果我取消注释seekp()行,写入开始工作:bad()返回false,并且字节实际上被写入.
为什么在这里需要seekp()为什么没有它呢? seekp()是正确的方法吗?
我在Windows 7上使用Visual Studio 2012.
解决方法
C标准(我引用C99,但在这一点上与C89没有区别)@H_404_18@在7.19.5.3/6状态:
When a file is opened with update mode (‘+’ as the second or third character in the@H_404_18@ above list of mode argument values),both input and output may be performed on the@H_404_18@ associated stream. However,output shall not be directly followed by input without an@H_404_18@ intervening call to the fflush function or to a file positioning function (fseek,@H_404_18@ fsetpos,or rewind),and input shall not be directly followed by output without an@H_404_18@ intervening call to a file positioning function,unless the input operation encounters end-@H_404_18@ of-file.
(我的重点).
所以你的stream.seekp(1)解决方案,下载到C fseek是正确的.
GNU C库没有此标准限制,因此您发布的代码有效@H_404_18@如同GCC建成的那样.
MS< fstream>图书馆符合C标准的继承@H_404_18@这个限制. fstreams使用basic_filebuf< charT,traits>实现.在(C11)标准的这个模板的第27.9.1.1/2段中,它简单地说:
The restrictions on reading and writing a sequence controlled by an object of class basic_filebuf are the same as for reading and writing with the Standard C library FILEs.