gpt4 book ai didi

c++ - 读取文件和未定义的行为

转载 作者:太空狗 更新时间:2023-10-29 21:14:17 25 4
gpt4 key购买 nike

最近我偶然发现了一个帖子:How to read an entire file into memory in C++其中描述了读取文件的不同技术。每种方法都对其效率或与未定义行为 相关的风险进行了评论。在列表中给出了以下示例:

// Bad code; undefined behaviour
in.seekg(0, std::ios_base::end);

基本上以这种或类似的形式经常用于实际读取文件大小。简而言之,帖子中提出的推理是,在 C 标准 (N1570) §7.21.3 中声明:

Setting the file position indicator to end-of-file, as with fseek(file, 0, SEEK_END), has undefined behavior for a binary stream (because of possible trailing null characters) or for any stream with state-dependent encoding that does not assuredly end in the initial shift state.

脚注 268 用于:

A file need not begin nor end in the initial shift state

为了确认 C++11 的上述内容,还有对 C++ 标准草案 (N3242) 27.9.1.1 的额外引用,其中指出:

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.

其中 basic_filebuf 根据 cppreferencebasic_ifstream(内部缓冲区)实现的一部分。 ifstream 实现也应该承担所指示的行为。

根据我从描述中了解到的内容和我设法挖掘的内容,这个问题主要与可能不会以 initial shift state 结束的宽向流有关。

在我看来,由于文件大小计算的流行用法,这不是典型案例。这个话题对我来说仍然不是很清楚。因此,以下问题:

  • 初始状态转换实际上是什么?我认为它与数据集群无关。更多关于多字节 char 编码,但这样问题不会仅限于非二进制流吗?
  • 我们什么时候真正处理wide-narrow-oriented流?我知道:“A newly opened stream has no orientation.” 方向是在对流的第一次 I/O 调用时决定的。但实际上,比方说,是否有任何默认值取决于流类型、系统、区域设置或其他因素?
  • 如果尚未回答或指出,关于何时可能发生此类未定义行为的实际示例是什么?从某种意义上说,人们可以复制它。

最佳答案

"shift state" - 仅限于多字节文本流(和 EOL 处理 \r\n\n )并且这个问题将仅限于文本流。

但这不是唯一的问题。从您引用的文章中,我强调:

Some platforms store files as fixed-size records. If the file is shorter than the record size, the rest of the block is padded. When you seek to the “end”, for efficiency’s sake it just jumps you right to the end of the last block… possibly long after the actual end of the data, after a bunch of padding.

fseek(p_file, 0, SEEK_END)其次是 ftell(...)只要 EOF 就提供有效答案旗帜没有升起。
阅读引用的“解决方案(真正的大文件)”部分,因为它提供了详细信息,特别是:
第 4 步。“使用 seekg() 将流恢复到起始位置。这也将清除 EOF 标志。"

评论中的问题:

do you have the knowledge which platforms particularly?

Google 将我带到了 this list面向记录的文件系统 - 主要是大型机,其中一些仍在使用。

另一个可能是“记录文件”区域的区域:“云端”。你永远不知道什么时候有人会(重新)化身Distributed Data Management Architecture并解决了 record-oriented files 可以解决的问题.据我所知(几乎什么都没有),NFS 可能 已经在这样做了:RFC谈到“记录锁定”。

最重要的是,在用 C/C++ 编写“真正标准的跨平台兼容软件”时,我会关注标准并尊重这个问题。

关于c++ - 读取文件和未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41214250/

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