0

I want to print UTF-8 characters with C programming language. I've tried this but failed:

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

int main(){
    if(setlocale(LC_ALL, "zh-CN.UTF-8")!=NULL){
        printf("Error.\n");
    }
    wchar_t *hello=L"你好";
    wprintf(L"%ls\n", hello);
}

And the result:

$ gcc main.c
$ a
??

You can follow the link to see the picture: https://i.stack.imgur.com/PZKaa.png.

Can anyone help me?

wjhtwx
  • 23
  • 4
  • Try to see if the answers to this question resolve: https://stackoverflow.com/questions/48730724/how-am-i-allowed-to-workaround-dos-functions-that-used-strings-containing-accent – Sir Jo Black Aug 05 '21 at 03:47
  • One of the suggestion in the answer is suggested you is: "don't mix: `printf` and `wprintf` on the same output stream!" (I remember, but read it). – Sir Jo Black Aug 05 '21 at 03:58
  • `L".."` is also wrong. UTF-8 uses `char` (and so, do not use `wprintf`). Just think UTF-8 as a 8-bit strings with "control character sequence/shifts". If you need more details, usually one need much more context (language are complex, so Unicode, so we have combining characters, and so on which must never be split from base character, etc.) [so but on real rendering engine, just image a 8-bit string much simpler] – Giacomo Catenazzi Aug 05 '21 at 08:08

2 Answers2

2

setlocale returns NULL on error.

You print an error message if setlocale returns something other than NULL, which means that the call succeeded. Your error message is not printed, so it appears that the call failed. That would explain the failure to turn the wchar_t* into UTF-8.

You might want to figure out why setlocale is failing, although it's probably because that locale is not installed. Of course, you should change the test to make it correct; then you can try to use perror to get a sensible error message. (It's quite possible that setlocale doesn't set errno to anything useful on your system. Still, it's worth a try.)

    if(setlocale(LC_ALL, "zh-CN.UTF-8") == NULL){
        perror("setlocale failed");
        exit(1);
    }

It's usually a bad idea to set the locale to anything other than "". The locale string "" is the locale currently configured in the terminal session, and you are relying on the terminal to correctly render the output. If you use a different locale than the terminal's, then output may be illegible.

rici
  • 234,347
  • 28
  • 237
  • 341
  • Fixed! Thank you very much! The following code worked as required. #include #include #include #include int main(){ if(setlocale(LC_ALL, "")==NULL){ wprintf(L"Error.\n"); } wchar_t hello=L'你'; wprintf(L"%lc\n", hello); } – wjhtwx Aug 05 '21 at 05:25
0

Thanks to rici. I followed him and the code worked as required.

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

int main(){
    if(setlocale(LC_ALL, "")==NULL){  //change: from "!=" to "==", "LC_ALL, \"zh-CN.UTF-8\"" to "LC_ALL, \"\"".
        wprintf(L"Error.\n");
    }
    wchar_t hello=L'你';
    wprintf(L"%lc\n", hello);
}

This code worked as required as well:

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

int main(){
    if(setlocale(LC_ALL, "")==NULL){
        wprintf(L"Error.\n");
    }
    wchar_t *hello=L"你好";
    wprintf(L"%ls\n", hello);
}

But if your operating system or console doesn't support UTF-8 or your language, the code would be useless. So you need to check your system before using utf-8. If it doesn't support your language, you should just use char.

wjhtwx
  • 23
  • 4