Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiplatform way to write a std::wstring into a file in C++

I've been struggling a lot to do something that looks simple: writing the contents to a std::wstring to the disk. Suppose I have the following string that I want to write into a plain text file:

std::wstring s = L"输入法."; // random characters pulled from baidu.cn
  1. Using std::codecvt_utf8 or boost locale

Here is the code I used:

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;

This works fine on Windows, but sadly I was compile it on Linux: codecvt_utf8 is not yet available on compilers provided with the usual distributions, and the Boost:Locale has only been included in Boost 1.60.0 which again is a version which is too recent for the distro's repositories. Without setting the locale, nothing is written to the file (on both systems).

  1. With fwrite

Next attempt:

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

This works on Windows, but does not write anything to the file on Linux. I also tried opening the file in binary mode, but that didn't change anything. Not setting the ccs part causes undecipherable garbage to be written to the file.

I'm obviously missing something here: what is the proper way to write that string to a file?

like image 684
executifs Avatar asked May 23 '16 15:05

executifs


1 Answers

You can use next code snipped. The difference from your code is that here I used std::codecvt_utf8 instead of 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";
}
like image 150
Ionut V. Avatar answered Sep 21 '22 15:09

Ionut V.