简体   繁体   中英

printing out a unicode character with printf

I am trying to print out a Ș by passing in its corresponding decimal value into printf. The output is nothing at all. Why doesn't my code work?

#include <stdio.h>
int main()
{
    printf("%lc",536);
    return 0;
}

The l length specifier applied to a c field descriptor indicates that the corresponding argument is of type wint_t (declared in wchar.h ). In your code, the argument is of type int , which might or might not be the same. If it indeed isn't the same then the behavior is undefined. You can obtain a wint_t by casting ...

    printf("%lc", (wint_t) 536);

; that's the safest and most portable way to express a wint_t constant.

Additionally, there is a potential question of character sets here. That's a matter of the environment in which your program runs, not so much the program itself. It is conceivable that your program indeed outputs the character in question, in some encoding, but the terminal in which you're running doesn't know how to handle it, or maybe just doesn't have a glyph for it. You should be able to test for that by redirecting the output to a file, and afterward examining the file's contents (possibly as a binary file).

On macOS Sierra 10.12.2 with GCC 6.3.0, if I run this program (compiled from mb37.c into mb37 ):

#include <locale.h>
#include <stdio.h>
#include <wchar.h>      /* wint_t */

int main(void)
{
    setlocale(LC_ALL, "");
    printf("%lc\n", (wint_t)536);
    return 0;
}

the output is:

$ ./mb37
Ș
$

That, I believe, is the desired output. If the setlocale() line is removed, then no output at all is produced — not even a newline. The locale used is en_US.UTF-8 ; my terminal handles UTF-8 too. The locale name is found by capturing and printing the return value from setlocale() — a regular string.

The wint_t cast is semi-optional; it so happens that a 64-bit compilation without the cast or the <wchar.h> header also produces the same output, but there is a mild coincidence that wint_t is the same as int . That takes some tracking; wint_t is defined as __darwin_wint_t which is defined as __darwin_ct_rune_t which is defined as int . To be portably correct, the cast is necessary. On some systems, it may not be necessary (and macOS Sierra is one such system).

The newline in the printf() is not 100% necessary, but if it is omitted, the next prompt immediately follows the U+0218 LATIN CAPITAL LETTER S WITH COMMA BELOW. It is better to ensure that the output ends with a newline.

There is no requirement in C that a line without a newline character at the end will be printed. Try "%lc\\n".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM