Ваш входной файл, вероятно, закодирован в многобайтовой кодировке. Это, по-видимому, не UTF-8, поскольку —
кодируется в UTF-8 как байты E2 80 94
, то есть —
при интерпретации в Latin-1, а ’
кодируется в UTF-8. в байтах E2 80 99
, что ’
при интерпретации в Latin-1. Это не то, что вы видите в своей продукции, хотя. Но симптом похож. Вы переворачиваете закодированные char
s в string
как есть, что не будет работать для многобайтовой кодировки.
Чтобы правильно перевернуть многобайтовую кодированную строку, вы должны знать кодирование заранее и прохождение по строке на основе этой кодировки, извлечение каждой целой последовательности закодированных блоков и сохранение каждого целого блока как есть на выходе, а не чтение и сохранение отдельных char
s как есть. std::reverse()
не может помочь вам в этом, если вы не используете итераторы, которые умеют читать и записывать эти целые единицы.
Если вы знаете кодировку заранее, вам может повезти с использованием std::wifstream
/ std::wofstream
вместо этого, где они imbue()
'с подходящим std::locale
для кодирования. Затем используйте std::wstring
вместо std::string
. Однако, по крайней мере, на Windows, где std::wstring
использует UTF-16, у вас все еще есть проблема работы с последовательностями из нескольких единиц (хотя и реже, если вы не имеете дело с восточноазиатскими языками). Таким образом, вам может потребоваться преобразовать декодированный вход UTF-16 в UTF-32 перед выполнением реверсирования (тогда вам придется иметь дело с кластерами графических кодов с несколькими кодовыми точками), затем преобразовать UTF-32 в UTF-16, а затем сохранить его в кодированном виде. выходной файл.
Кроме того, если вы собираетесь обрабатывать отдельные char
s как есть, чтобы обеспечить правильное чтение и запись необработанных char
s, вы должны открыть файлы в двоичном режиме. и используйте неформатированные операции ввода / вывода (ie, нет operator>>
или operator<<
):