Мультиплатформенный способ записи std:: wstring в файл на С++

Я много пытаюсь сделать то, что выглядит просто: записывая содержимое в std:: wstring на диск. Предположим, у меня есть следующая строка, которую я хочу записать в текстовый файл:

std::wstring s = L"输入法."; // random characters pulled from baidu.cn
  • Использование std::utf8_codecvt или повышение языкового стандарта

Вот код, который я использовал:

std::wofstream out(destination.wstring(), std::ios_base::out | std::ios_base::app);
const std::locale utf8_locale = std::locale(std::locale(), new boost::locale::utf8_codecvt<wchar_t>());
out.imbue(utf8_locale);
// Verify that the file opened correctly
out << s << std::endl;

Это отлично работает в Windows, но, к сожалению, я скомпилировал его в Linux: utf8_codecvt пока недоступен в компиляторах с обычными дистрибутивами, а Boost: Locale включен только в Boost 1.60.0, который снова версия, которая слишком поздняя для репозиториев дистрибутивов. Не устанавливая язык, ничего не записывается в файл (в обеих системах).

  1. С fwrite

Следующая попытка:

FILE* out = fopen("test.txt", "a+,ccs=UTF-8");
fwrite(s.c_str(), wcslen(s.c_str()) * sizeof(wchar_t), 1, out);
fclose(out);

Это работает в Windows, но ничего не записывает в файл в Linux. Я также попытался открыть файл в двоичном режиме, но это ничего не изменило. Не устанавливая часть ccs, в файл записывается неразборчивый мусор.

Мне явно не хватает чего-то здесь: как правильно записать эту строку в файл?

Ответы

Ответ 1

Вы можете использовать следующий код. Отличие от вашего кода в том, что здесь я использовал std:: codecvt_utf8 вместо boost:: locale....

#include <locale>
#include <codecvt>

----

std::wstring s = L"输入法.";

const std::locale utf8_locale = std::locale(std::locale(), new std::codecvt_utf8<wchar_t>());

myfile.open("E:/testFile.txt");
if (myfile.is_open())
{
    myfile.imbue(utf8_locale);
    myfile << s << endl;
    myfile.close();
}
else
{
    std::cout << "Unable to open file";
}

Ответ 2

Типы потоков всегда выводят ASCII-вывод, даже если входные данные являются Unicode. Во-первых, вы должны настроить языковой стандарт для своего вывода. Только позже вы должны написать что-нибудь в файл. Я думаю, этот пример должен помочь вам. Я запускал его на Ubuntu.

#include <cstdio>
#include <cwchar>
#include <string>
#include <locale>

void write_string(FILE *fd, std::wstring str)
{
    std::fputws(str.c_str(), fd);
}

int main()
{
    setlocale(0, "");
    FILE *fd = std::fopen("./test.txt", "w");

    write_string(fd, L"输入法.");

    std::fclose(fd);

    return 0;
}