wprintf does not work correctly.

Started by edison, June 08, 2014, 08:31:43 PM

Previous topic - Next topic

edison

The code:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(void)
{
    setlocale(LC_ALL, "");

    wchar_t * a = L"中文";

    wprintf(L"%ls\n", a);
    wprintf(L"%ls\n", L"中文");

    return 0;
}


output:

Pelles C RC4 (-std:C11 -Tx64-coff -Ot -Ob1 -fp:precise -W1 -Gr)
Windows 8.1 x64 CHS
-?
-?
Press any key to continue...


MinGW 4.8.1
Windows 8.1 x64 CHS
中文
中文

Process returned 0 (0x0)   execution time : 0.013 s
Press any key to continue.

jj2007

To use "true" Unicode (i.e. not ASCII extended to WORDs), you need a stringtable in a resource file, such as
STRINGTABLE
BEGIN
001, "Enter text here"
002, "Click on this button"
003, "Welcome"
401, "Введите текст  здесь" ; "Enter text here" in Russian
402, "Нажмите на эту кнопку" ; "Click on this button" in Russian
403, "Добро пожаловать" ; "Welcome" in Russian
801, "أدخل النص هنا" ; "Enter text here" in Arabic
802, "دفع هذا الزر" ; "Click on this button" in Arabic
803, "مرحبا بكم" ; "Welcome" in Arabic
1201, "在這裡輸入文字" ; "Enter text here" in Chinese
1202, "按一下這個按鈕" ; "Click on this button" in Chinese
1203, "歡迎" ; "Welcome" in Chinese
END

edison

You meant wprintf in Pelles C is a fake wide character implement?

jj2007

No idea. Does somebody know how to get this snippet work properly?

#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#define UNICODE
int main(void)
{
    setlocale(LC_ALL, "");

    wchar_t * a = L"控";
    wprintf(L"%ls\n", a);
    wprintf(L"%ls\n", L"アア");
    printf("%s\n", "OK?");

    return 0;
}

frankie

#4
The problem is much bigger than it could appear.
The console is a text output device and it must be so because you can redirect its input and output to other programs (pipes).
So whichever language you would use its I/O is always text not wide text. In chinese the characters can be represented by mutibyte strings, *note* multibyte not unicode chars.
To guarantee that the whole OS utilities understood the correct encoding there are a lot of things, or should say hacks, like codepages, regional settings, fonts, etc.
For these reasons, and many others, is very difficult to print special characters in a cosolle. While it is relatively easy to print latin alphabet in all available codepages (because normally it is always present as the first 127 codes), is not that simple for the reverse.
If your machine has regional setting for simplifyied chinese something like:

SetFileApisToOEM();
SetConsoleOutputCP(65001);      //Unicode codepage (but doesn't work if you don't have chines or whatever, configured OS)
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"中文", 2, &n, NULL);

should work, but I can't test it.
Of course the source file must be UTF-8 encoded, or the unicode characters will be seen as 'trigraphs' by the compiler an the output will fail.
With former settings also wprintf should work (but as above I can't check on my machine).
I suppose that MingW, and maybe even MSVC, works because their runtime 'prepare' the consolle for output, PellesC is a little bit less smart, but consolle internalization is not a core interest of the compiler. If you need to allow multilingual support you will normally use a GUI interface, not the limited consolle.
Anyway if google around for 'print chinese on consolle', or the like, you will see that the problem is very very diffused.
Moreover, because it is a real pain in ... , also MS people keeps at a far distance from it  >:(
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

neo313

I can't get unicode characters to work even when displaying a messagebox.


#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#include <windows.h>
#define UNICODE
int WINAPI wWinMain(HINSTANCE h , HINSTANCE p , wchar_t* c , int s )
{
    setlocale(LC_ALL, "");

    wchar_t * a = L"控控控控控控";

MessageBoxW( NULL , a , NULL , MB_OK ) ;

    return 0;
}


When I run the program the characters in the code the debugger shows, turn into question marks. And the message box shows questions marks as well.


wchar_t * a = L"??????";


I'm must be missing something.

JohnF

Quote from: JohnF on June 11, 2014, 04:19:05 PM
I just tried this and it was ok. You need to create a unicode file containing your code - then load it into POIDE.


#include <windows.h>

int WINAPI wWinMain(HINSTANCE h , HINSTANCE p , wchar_t* c , int s )
{
    wchar_t * a = L"控控控控控控";
MessageBoxW( NULL , a, a, MB_OK ) ;
    return 0;
}


John

neo313

Quote from: JohnF on June 11, 2014, 04:19:42 PM
Quote from: JohnF on June 11, 2014, 04:19:05 PM
I just tried this and it was ok. You need to create a unicode file containing your code - then load it into POIDE.


#include <windows.h>

int WINAPI wWinMain(HINSTANCE h , HINSTANCE p , wchar_t* c , int s )
{
    wchar_t * a = L"控控控控控控";
MessageBoxW( NULL , a, a, MB_OK ) ;
    return 0;
}


John

Thanks that worked, I can't believe I didn't try that.


jj2007

Doesn't work for me - just cryptic error messages:

> pocc.exe -std:C11 -Tx86-coff -Ot -Ob1 -fp:precise -W1 -Gd  "D:\Masm32\PellesC\Projects\UnicodeConsole\Main.c" -Fo"D:\Masm32\PellesC\Projects\UnicodeConsole\output\Main.obj"
D:\Masm32\PellesC\Include\Win\basetsd.h(53): error #2001: Syntax error: expected ';' but found 'INT64'.
D:\Masm32\PellesC\Include\Win\basetsd.h(53): warning #2099: Missing type specifier; assuming 'int'.
D:\Masm32\PellesC\Include\Win\winnt.h(559): fatal error #1014: #error: "No target architecture".
*** Error code: 1 ***

neo313

Quote from: jj2007 on June 11, 2014, 10:30:29 PM
Doesn't work for me - just cryptic error messages:

> pocc.exe -std:C11 -Tx86-coff -Ot -Ob1 -fp:precise -W1 -Gd  "D:\Masm32\PellesC\Projects\UnicodeConsole\Main.c" -Fo"D:\Masm32\PellesC\Projects\UnicodeConsole\output\Main.obj"
D:\Masm32\PellesC\Include\Win\basetsd.h(53): error #2001: Syntax error: expected ';' but found 'INT64'.
D:\Masm32\PellesC\Include\Win\basetsd.h(53): warning #2099: Missing type specifier; assuming 'int'.
D:\Masm32\PellesC\Include\Win\winnt.h(559): fatal error #1014: #error: "No target architecture".
*** Error code: 1 ***

Where is the -ze flag?

Enable it: project options >> compiler >> options >> enable Microsoft ext

jj2007

Quote from: neo313 on June 11, 2014, 11:13:09 PM
Where is the -ze flag?

Enabled: -subsystem:console -machine:x86 kernel32.lib advapi32.lib delayimp.lib

Now the errors are

Building Main.obj.
Building UnicodeConsole.exe.
POLINK: error: Unresolved external symbol '__imp__MessageBoxW@16'.
POLINK: error: Unresolved external symbol '_main'.
POLINK: fatal error: 2 unresolved external(s).
*** Error code: 1 ***
Done.

frankie

Be sure that 'user32.lib ' library is included (in linker tab).
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

jj2007

Thanks, that reduces the list to one:
POLINK: error: Unresolved external symbol '_main'.

czerny

Have you created this as a windows project or a console project?

frankie

Add '-subsystem:windows' on linker command line or select subsystem=windows form linker tab.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide