Почему `ofstream` пропускает некоторые строки при записи в файл? - PullRequest
0 голосов
/ 18 июня 2019

Я сгенерировал кучу строк 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, потому что хочу сохранить память, и я полагаю, что эти два не должны конфликтовать.

На самом деле я не уверен, задаю ли я правильный вопрос, но я предполагаю, что это как-то связано с моим использованием ofstream и char16_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() с никогда не равна нулю и на самом деле выглядит совершенно нормально. Так куда же деваться содержимое? Они не могут просто исчезнуть в забвении.

В случае, если это имеет значение, я нахожусь на macOS 10.14.5 с использованием gcc версии 9.1.0 (Homebrew GCC 9.1.0).

...