在二进制文件上使用Getline

问题描述 投票:3回答:2

我已经读过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, '\0');

这打破了任何规则吗? 它似乎工作正常,我想我传统上看到的数组通过写入大小然后编写数组来处理。

c++ string binaryfiles getline null-terminated
2个回答
3
投票

不,它没有打破我能看到的任何规则。

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

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

哪个更好取决于你想要阅读文件的随机部分而不是从头到尾阅读它的可能性,以及找到唯一分隔符的困难(如果有的话)以及你是否有一个,使分隔符可以从字段内的数据识别的复杂性。 如果数据只有按顺序写入才有意义,那么必须按顺序读取它并不会造成问题。 如果你能够有意义地阅读各个部分,那么能够更有可能做到这一点。

最后,它归结为一个问题,你想要从你的文件中得到什么是“二进制”。在典型的情况下,所有'二进制'实际上意味着可能从新行翻译的行标记的哪一端(例如)回车/换行对的字符不会。 根据您使用的操作系统,它甚至可能意味着很多 - 例如,在Linux上,二进制和文本模式之间通常没有区别。


1
投票

好吧,没有规则被破坏,你可以侥幸逃脱,除了可能会错过从流对象读取二进制文件的精度。

使用二进制输入,您通常想知道成功读取了多少个字符,之后可以使用gcount()获取...使用std::getline不会反映gcount()读取的字节数。

当然,您可以从传递给std::getline的字符串大小中获取此类信息。 但是流将不再封装您在上一次无格式操作中消耗的字节数

© www.soinside.com 2019 - 2024. All rights reserved.