为什么`ofstream`在写入文件时会丢失某些行?

时间:2019-06-18 12:35:08

标签: c++ fstream unicode-string

我已经生成了一堆UTF-16LE字符串(3.8k +,\n终止)以写入仍在UTF16中的文本文件。最终文件中不知何故这些字符串的一部分(〜1.7k)丢失了。该错误不是随机的,无论我如何尝试编写书写部分,缺失的部分都是固定的。

这是我使用的代码(略作释义):

inline std::u16string str_u8_to_u16(const std::string & u8_str){
  return std::wstring_convert<
    std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(u8_str);
}

std::ofstream fout("output.txt", std::ios::trunc);
extern std::vector<std::pair<char16_t, std::size_t> > str_vec;

for (auto itr = str_vec.cbegin(); itr != str_vec.cend(); ++itr) {
  std::u16string line_to_write = std::u16string(1, itr->first) + u"\t"
                               + str_u8_to_u16(std::to_string(itr->second)) + u"\n";
                               // because the second term can be greater than 9
  // byte-by-byte write
  fout.write(reinterpret_cast<const char*>(line_to_write.c_str()),
             line_to_write.size() * 2);

  fout.flush();
}

我想在循环中插入flush()可以解决问题,但是不,该错误仍然存​​在。我没有尝试过wchar_t,因为我想节省内存,我认为这两个不应该冲突。

我实际上不确定我是否在问正确的问题,但是我猜想这与我对ofstreamchar16_t的使用有关。

我什至尝试过:

for (auto itr = str_vec.cbegin(); itr != str_vec.cend(); ++itr) {
  std::u16string line_to_write = std::u16string(1, itr->first) + u"\t" 
                               + str_u8_to_u16(std::to_string(itr->second)) + u"\n";
  auto end_before_write = fout.tellp();
  fout.write(reinterpret_cast<const char*>(line_to_write.c_str()),
             line_to_write.size() * 2);
  auto end_after_write = fout.tellp();
  std::cerr << std::dec << "end_before_write = " << end_before_write
            << ", end_after_write = " << end_after_write
            << ", diff = " << end_after_write - end_before_write << std::endl;
  fout.flush();
}

结果更加令人困惑:两个tellp()的差永远不会为零,实际上看起来是完全正常的。那么内容在哪里呢?他们不能只是消失而忘却。

万一重要,我使用的是gcc版本9.1.0(Homebrew GCC 9.1.0)的macOS 10.14.5。

0 个答案:

没有答案