gpt4 book ai didi

c++ - 使用同一个 fstream 读写同一个文件

转载 作者:IT老高 更新时间:2023-10-28 22:35:01 26 4
gpt4 key购买 nike

我有一个已经包含一些数据的文件(比如 8 kB)。我想从文件的开头读取一些东西,然后从我读完的地方开始覆盖数据。所以我尝试使用以下代码:

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。

最佳答案

您违反了对 read 和对 MS 的 fstream 以更新模式打开的文件的写操作库继承自其 C <stdio.h>实现。

C 标准(我引用 C99,但在这一点上它与 C89 没有区别)在 7.19.5.3/6 状态:

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), 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.

(我的重点)。

所以你的stream.seekp(1)解决方案,该解决方案转移到 C fseek , 是正确的。

GNU C 库没有此标准限制,因此您发布的代码可以正常工作使用 GCC 构建时符合预期。

MS <fstream>库在继承方面符合 C++ 标准这个限制。 fstream s 使用 basic_filebuf<charT,traits> 实现.在 (C++11) 标准对该模板的说明中,第 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.

关于c++ - 使用同一个 fstream 读写同一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17536570/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com