4

I got seperated parts from 22 files in different languages and made them a wstring line like:

wstring wstr_line = L"\"IDS_TOAST_ECOON\",\"eco Mode is turned On.\",\"ecoモードをオンにしました。\",\"Režim eco je zapnutý.\",\"Økoindstillingen er aktiveret\"..."

I used wofstream to put wstr_line into a file, but the line finished at Japanese part(\"ecoモードをオンにしました。\"). If I set wfout.imbue("chs"); the line finished at Czech part(\"Režim eco je zapnutý.\")

How can write this line to a file correctly?

ST3
  • 8,826
  • 3
  • 68
  • 92
goss.beta
  • 103
  • 2
  • 7
  • possible duplicate of [Writing utf16 to file in binary mode](http://stackoverflow.com/questions/207662/writing-utf16-to-file-in-binary-mode) – Martin York Jul 30 '12 at 04:40
  • Also I notice that your string does not start with an L as in `L"Text"`. Is this a typo? As this mean the text in your code is not wchar_t* but char*. Which suggests that the string is encoded as UTF-8. – Martin York Jul 30 '12 at 04:58

2 Answers2

0

Try sticking this as the first line in your code:

int main()
{
    std::cout.imbue(std::locale(""));

This sets the local of the application to what the machine supports (which is probably UTF-32 for wide character strings). Unfortunately the default local is "C" for programers and the codecvt facet for the "C" local does not do anything useful (probably truncates wide charters to a single byte without conversion).

Martin York
  • 257,169
  • 86
  • 333
  • 562
  • but there are different languages in the line, if I set a locale,then other languages can not output correctly... – goss.beta Jul 30 '12 at 06:34
  • 1
    @goss.beta: That's not how it works. What we are looking for here are the codecvt facets to kick in correctly. These are not used to convert between languages but between encoding formats. Assuming your system is using UTF (most likely) then it will output the appropriate UTF. Give it a try and see what happens. – Martin York Jul 30 '12 at 07:10
0

I've solved the problem in another strategy, output the lines in bytes. Use the function below to output the wstring no matter what chracter it contains.

void output(ofstream &fout, vector<wstring> wline_list)
{
    void outputline(ofstream &, wstring);
  //pre output 0xFF and 0xFE to make the file encoding in UTF-16
    const BYTE PRE_LOW = 0xFF;
    const BYTE PRE_HIGH = 0xFE;
    fout << PRE_LOW << PRE_HIGH;
    for(vector<wstring>::size_type i(0); i<wline_list.size(); i++)
        outputline(fout, wline_list[i]);
}

void outputline(ofstream &fout, wstring line)
{
    void getByte(BYTE btchar[2], WORD wdChar);
    BYTE btChar[2] = {0,0};

    const BYTE CHANGE_LINE1_LOW = 0x0D;
    const BYTE CHANGE_LINE1_HIGH = 0x00;
    const BYTE CHANGE_LINE2_LOW = 0x0A;
    const BYTE CHANGE_LINE2_HIGH = 0x00;

    WORD wdChar(0);
    for(wstring::size_type i(0); i<line.length(); i++)
    {
        wdChar = line[i];
        getByte(btChar, wdChar);
        fout << btChar[0] << btChar[1];
    }
  //it needs this two chars to change line.
    fout << CHANGE_LINE1_LOW << CHANGE_LINE1_HIGH
        << CHANGE_LINE2_LOW << CHANGE_LINE2_HIGH;
}

void getByte(BYTE btchar[2], WORD wdChar)
{
    btchar[0] = wdChar % 0x0100;
    btchar[1] = wdChar / 0x0100;
}
goss.beta
  • 103
  • 2
  • 7