不使用eekp值编写函数

发布于 2024-12-12 13:22:33 字数 471 浏览 2 评论 0原文

我正在尝试使用 C++ 在文件中的特定位置写入一个条目,

所以基本上我有

ofstream ofs("file.dat", ios::binary | ios::app);
ofs.seekp(220, ios::beg);
ofs.write((char *)&i, sizeof(i));

但无论我做什么,它总是写在文件的末尾。

我想这与 iso::app 有关,因为根据文档,

app (append) Set the stream's position indicator to the end of the stream before each output operation

但是如果我使用 ate 或什么都不使用,它总是会删除文件的内容。

任何帮助都会很棒:)

I'm trying to use C++ to write an entry in a specific place in a file

so basicly I have

ofstream ofs("file.dat", ios::binary | ios::app);
ofs.seekp(220, ios::beg);
ofs.write((char *)&i, sizeof(i));

But no matter what I do it always write at the end of the file.

I suppose this is related to iso::app because according to the documentation

app (append) Set the stream's position indicator to the end of the stream before each output operation

But if I use ate or nothing it always erases the content of the file.

Any help would be great :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

娇纵 2024-12-19 13:22:33

是的,正是 ios::app 导致了这种行为。将其替换为 ios::in | ios::out。

编辑:您的问题并不清楚,但您的评论表明您正在尝试在文件中间插入数据,而不是覆盖 文件的一部分。如果确实如此,您几乎必须使用第二个文件。

Yes, it's the ios::app that's causing this behaviour. Replace it with ios::in | ios::out.

edit: It wasn't clear from your question, but your comments suggest that you're trying to insert data in the middle of the file, rather than overwrite a portion of the file. If that is indeed the case, you pretty much have to use a second file for that.

檐上三寸雪 2024-12-19 13:22:33

文件追加模式

如果操作系统(和网络文件系统,如果适用)支持追加模式,则设置追加模式可保证在有多个写入者时写入的数据不会覆盖文件中的现有数据。如果没有附加模式,这是无法做到的,因为不同进程的查找和写入之间存在竞争。是日志文件的重要保障。

在附加模式下,根据定义只能在文件末尾写入。

iostream打开模式

根据[ofstream.cons],ofstream(s, mode)调用rdbuf()->open(s, mode|ios_base::out)

根据[filebuf.members]中的“文件打开模式”表,filebuf::open的行为是根据fopen打开模式定义的:

  • out 表示“w”
  • appapp|out 表示“a”
  • in|out 表示“r+”
  • in| out|trunc 表示“w+”

根据fopen man,模式含义:

  • r+ 打开以进行读写。
  • w 将文件截断为零长度或创建用于写入的文本文件。
  • w+ 打开以进行读取和写入。如果文件不存在则创建该文件,否则将被截断。
  • a 打开以追加(写在文件末尾)。如果文件不存在,则创建该文件。

最后,ate 表示 fseek(file,0,SEEK_END)

所以,如果你想在任意位置打开写入,而不破坏现有数据,你需要 fopen(s,"r+") 或 ofstream (s, ios::in|ios ::输出)。

IOW,在 C/C++ 中,您还需要对文件进行读取访问才能打开它进行写入而不覆盖它!

POSIX 世界

您可能想要使用 POSIX open 函数,以便直接访问 POSIX open 标志:O_READO_WRITEO_CREATO_EXCLO_TRUNC...它们不仅功能强大得多,而且具有独立的正交标志并且行为良好,不像filebuf::open 标志。

当然,这个函数不是标准 C++ 的一部分。我相信所有与正常编程相关的系统(不是具有特殊特征的利基市场)都支持开放

File append mode

If the OS (and network file system, if applicable) supports append mode, setting append mode guarantees that data written does not overwrite existing data in the file when there are multiple writers. That's something you cannot do without append mode, because of the race between seek and write from different processes. It is an important guarantee for log files.

In append mode, you can only write at end of file by definition.

Iostream open modes

According to [ofstream.cons], ofstream (s, mode) calls rdbuf()->open(s, mode|ios_base::out).

According to the table "File open modes" in [filebuf.members], the behaviour of filebuf::open is defined in term of fopen open modes:

  • out means "w"
  • app and app|out mean "a"
  • in|out means "r+"
  • in|out|trunc means "w+"

According to fopen man, the modes mean:

  • r+ Open for reading and writing.
  • w Truncate file to zero length or create text file for writing.
  • w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated.
  • a Open for appending (writing at end of file). The file is created if it does not exist.

Finally, ate means fseek(file,0,SEEK_END).

So, if you want to open for writing at arbitrary position, without destroying the existing data, you need fopen(s,"r+") or ofstream (s, ios::in|ios::out).

IOW, in C/C++ you also need read access to a file to open it for writing without overwriting it!

POSIX world

You may want to use the POSIX open function instead, in order to directly access the POSIX open flags: O_READ, O_WRITE, O_CREAT, O_EXCL, O_TRUNC... They are not only much more powerful, but also independent orthogonal flags and well-behaved, unlike filebuf::open flags.

Of course, this function is not part of standard C++. I believe all systems relevant for normal programming (not niche markets with special characteristics) support open.

橪书 2024-12-19 13:22:33

您是否尝试过使用 ios::out 而不是 ios::app ?

编辑:

阅读 @curiousguy 引用的文档后,您似乎需要 ios::in | ios::out 而不仅仅是 ios::out 以防止截断。

Have you tried using ios::out instead of ios::app?

EDIT:

After reading the docs that @curiousguy referenced it looks like you would need ios::in | ios::out instead of just ios::out to keep from truncating.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文