Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unicode chars in console through C++

Windows 8 x64; Visual Studio 2012;

I learn C++ by book. On this forum I found many themes about read\write Unicode strings through C++. But this themes not marked as solved(???). Is it really big problem in C++? I have tried different variants - they not working to me:

#include<iostream>
#include<Windows.h>
#include <io.h>
#include <fcntl.h>
using namespace std;

int main() {
    // variant 1:
    wcout << L"Hello World!" << endl; // displayed
    wcout << L"Привет Мир!" << endl;// not displayed

    //**********************************************

    // variant 2:
    SetConsoleOutputCP(CP_UTF8);
    wchar_t s[] = L"Hello World (2)!";
    int bufferSize = WideCharToMultiByte(CP_UTF8, 0, 
        s, -1, NULL, 0, NULL, NULL);
    char* m = new char[bufferSize]; 
    WideCharToMultiByte(CP_UTF8, 0, s, -1, m, 
        bufferSize, NULL, NULL);

    wprintf(L"%S", m); // valid output
    wcout << endl;
    printf("%s", m); // valid output
    wcout << endl;

    wchar_t s2[] = L"Привет мир (2)!";
    int bufferSize2 = WideCharToMultiByte(CP_UTF8, 0, 
        s2, -1, NULL, 0, NULL, NULL);
    char* m2 = new char[bufferSize2]; 
    WideCharToMultiByte(CP_UTF8, 0, s2, -1, m2, 
        bufferSize2, NULL, NULL);

    wprintf(L"%S", m2); // invalid output
    wcout << endl;
    printf("%s", m2); // invalid output
    wcout << endl;
    //**********************************************

    // variant 3 (not working):
    _setmode(_fileno(stdout), _O_U16TEXT);
    wcout << L"Testing unicode -- English -- Ελληνικά"
        << "-- Español." << endl;

    return 0;
}

But it works for English chars only... Screen:

enter image description here

How can I solve it problem through C++?

like image 612
Andrey Bushman Avatar asked Dec 21 '25 16:12

Andrey Bushman


2 Answers

The workaround for this is executing

chcp 65001

in cmd.exe before executing your program (I don't know how to do that programmatically). 65001 is a magic value for UTF8 encoding. List of other code pages available for chcp is here: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx?mfr=true . Other interesting value is 855 for Cyrillic CP1251.

And don't forget to switch the console font to Lucida (the default font does not work with UTf-8).

like image 143
Dmytro Sirenko Avatar answered Dec 23 '25 06:12

Dmytro Sirenko


I found more simple variant (without changing of code page, and font):

#include<iostream>
#include<windows.h>

using namespace std;
int main()
{
    cout<<"Привет мир (1)!" << endl; // invalid output

    SetConsoleCP(GetACP());
    SetConsoleOutputCP(GetACP());

    cout<<"Привет мир (2)!" << endl; // valid output!

    return 0;
}

Maybe it will interesting not for me only.

P.S. But... It works in CMD.EXE, but not works in POWERSHELL.EXE.

like image 43
Andrey Bushman Avatar answered Dec 23 '25 05:12

Andrey Bushman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!