在二进制文件上使用 Getline

Using Getline on a Binary File

我读到 getline 表现为未格式化的输入函数。我认为应该允许它在二进制文件上使用。比方说我已经这样做了:

ofstream ouput("foo.txt", ios_base::binary);
const auto foo = "lorem ipsum";

output.write(foo, strlen(foo) + 1);
output.close();

ifstream input("foo.txt", ios_base::binary);
string bar;

getline(input, bar, '[=10=]');

这是否违反任何规则?它似乎工作正常,我想我只是传统上看到通过写入大小然后写入数组来处理数组。

不,据我所知,它没有违反任何规则。

是的,写一个带有前缀大小的数组更常见,但是使用分隔符来标记结束也可以很好地工作。最大的区别在于(就像文本文件一样)您必须通读数据才能找到下一个项目。有前缀尺寸,可以看尺寸,不需要当前的直接跳到下一项。当然,您还需要确保如果您使用某些东西来标记字段的结尾,它永远不会出现在字段内(或者想出一些检测它何时在字段内的方法,这样您就可以阅读剩下的字段。

根据情况,这可能意味着(例如)使用 Unicode 文本。这为文本中不能出现的值提供了很多选项(因为它们不是合法的 Unicode)。另一方面,这也意味着您的 "binary" 文件实际上是一个文本文件,必须遵循一些基本的文本文件规则才能有意义。

哪个更可取取决于您想要随机读取文件片段而不是从头到尾通读文件的可能性有多大,以及找到唯一分隔符的难度(如果有的话)如果您没有,那么从字段内的数据中识别分隔符的复杂性。如果数据只有按顺序写入才有意义,那么必须按顺序读取它并不会真正造成问题。如果您可以有意义地阅读个别文章,那么能够这样做更有用。

最后,它归结为一个问题,即您希望从文件中得到什么 "binary'. In the typical case, all 'binary" 的真正意思是行尾标记可以从换行符转换为 (例如) carriage-return/line-feed 对,不会。根据您使用的 OS,它甚至可能意义不大——例如,在 Linux 上,二进制模式和文本模式之间通常没有任何区别。

好吧,没有违反任何规则,你会很好地摆脱它,除了可能会错过从流对象读取 binary 的精度。

对于二进制输入,你通常想知道有多少个字符被读取成功,之后你可以用gcount()... Using std::getline will not reflect the bytes read in gcount()获得。

当然,您可以简单地从传递给 std::getline 的字符串的大小中获取此类信息。但是stream将不再封装你上次Unformatted Operation消耗的字节数