【问题标题】:why std::wofstream do not print all wstring into file?为什么 std::wofstream 不将所有 wstring 打印到文件中?
【发布时间】:2013-08-14 08:30:23
【问题描述】:

我有一个std::wstring,其大小为 139,580,199 个字符。

为了调试,我使用以下代码将其打印到文件中:

std::wofstream f(L"C:\\some file.txt");
f << buffer;
f.close();

之后注意到缺少字符串的结尾。创建的文件大小为 109,592,584 字节(“磁盘大小”为 109,596,672 字节)。

还检查缓冲区是否包含空字符,这样做:

size_t pos = buffer.find(L'\0');

期望结果是std::wstring::npos,但它是18446744073709551615,但我的字符串末尾没有空字符,所以可能没问题。

谁能解释一下,为什么我没有将所有字符串都打印到文件中?

【问题讨论】:

  • 关于 find,你是说你的缓冲区没有以 \0 结尾,所以 find 超出了结尾?
  • 如果缓冲区是wstring,则不必在其中包含L'\0'。我希望我们不能使用find 来定位基本字符数组中的东西[至少在 1.4MB 时不能]。
  • Expecting result to be std::wstring::npos but it is 18446744073709551615 为什么你认为这不是std::wstring::npos
  • @Mats: 实际上是 133MB,但是为什么你认为“我们不能使用 find 来定位基本字符数组中的东西”?
  • @LightnessRacesinOrbit 基本字符数组 (char[]) 没有成员函数 find。 (但这里没有基本的 char 数组。虽然他实际上并没有显示 buffer 的定义,但周围的文字清楚地表明它是一个 std::wstring。)

标签: c++ ofstream wstring wofstream


【解决方案1】:

很大程度上取决于语言环境,但通常情况下,磁盘上的文件会 不使用相同的编码形式(甚至相同的编码) wchar_t 使用的那个; filebuf 执行实际操作 读写根据其翻译编码 灌输的语言环境。而且两者之间只有一种模糊的关系 不同编码或编码形式的字符串的长度。 (并且系统看到的大小并不直接对应于 您可以从文件中读取的字节数。)

要查看是否所有内容都已写入,请检查f 的状态 结束后,即:

f.close();
if ( !f ) {
    //  Something went wrong...
}

可能出错的一件事是外部编码 没有字符之一的表示。如果 您在 "C" 语言环境中,这可能发生在任何字符上 在基本执行字符集之外。

如果上面没有错误,就没有理由假设 并非所有字符串都已写入。如果发生什么 您尝试在另一个程序中阅读它吗?你得到同样的 字符数?

对于其余的,nul 字符和其他字符一样 一个std::wstring;它们没有什么特别之处,包括 当它们输出到流时。和 18446744073709551615 看起来非常像我期望的价值 std::wstring::npos 在 64 位机器上。

编辑:

跟进 Mat Petersson 的评论:实际上是高度 文件最终的字节数不太可能少于 std::wstring 中的代码点。 (std::wstring::size() 返回代码点的数量。)我在考虑 字节,而不是 std::wstring::size() 返回的内容。所以 最可能的解释是你有一些字符 您的字符串在目标编码中无法表示 (这可能只支持带有代码点的字符 32-126,加上几个控制字符,默认)。

【讨论】:

  • 当然,文件大小不能比字符串中的字符数少 tho',所以编码应该无关紧要 - 或者我错过了一些关于 size 如何工作的内容wstring(我确实检查了它是“字符长度”,而不是字节长度 - 因为我在想一些东西是 UTF-8 与 16 位 unicode 编码)。
  • @MatsPetersson 我认为您对文件大小的看法是正确的。在这两种情况下,我都在考虑字节数:文件大小当然可以小于std::wstring 中的字节数。理论上,它也可以小于std::wstring 中的代码点数(例如,如果字符串包含可以由外部编码中的单个字符表示的组合字符),但很难想象一个案例真正发生的地方。
  • @JamesKanze 在 Windows 上,宽字符串只有 16 位,因此代码点可能比单个“字符”长,如果是语言环境问题,则组合字符可能无法在默认语言环境。具有许多组合字符的语言的窗口上的文本也具有基本多语言平面之外的许多字符,可能会产生这种结果。不是很常见,我承认,但有可能。
  • @MadKeithV 即使使用 UTF-32,在某些情况下,两个代码点序列也可能导致目标集中的单个字符:Unicode \u0065\u0301 映射到 ISO 8859-1 中的 0xE9,例如。 (但是任何实际的实现是否正确地做到了这一点?)
猜你喜欢
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 2012-02-05
  • 2021-10-29
  • 1970-01-01
  • 2011-05-13
相关资源
最近更新 更多