it-swarm.com.de

drucken eines Unicode-Zeichens mit printf

Ich versuche, einen Ș auszudrucken, indem ich den entsprechenden Dezimalwert in printf übergebe. Die Ausgabe ist überhaupt nichts. Warum funktioniert mein Code nicht?

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

Wenn Sie dieses Programm unter macOS Sierra 10.12.2 mit GCC 6.3.0 ausführen (kompiliert aus mb37.c in 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;
}

die Ausgabe ist:

$ ./mb37
Ș
$

Ich glaube, das ist der gewünschte Output. Wenn die setlocale()-Zeile entfernt wird, wird überhaupt keine Ausgabe erzeugt - nicht einmal eine Newline. Das verwendete Gebietsschema lautet en_US.UTF-8; Mein Terminal kann auch mit UTF-8 umgehen. Der Name des Gebietsschemas wird ermittelt, indem der Rückgabewert von setlocale() - einer regulären Zeichenfolge - erfasst und gedruckt wird.

Der wint_t-Cast ist semi-optional. Es kommt daher vor, dass eine 64-Bit-Kompilierung ohne die Besetzung oder den <wchar.h>-Header auch die gleiche Ausgabe erzeugt, es besteht jedoch ein leichter Zufall, dass wint_t mit int identisch ist. Das erfordert etwas Verfolgung; wint_t ist definiert als __darwin_wint_t, definiert als __darwin_ct_rune_t, definiert als int. Um portabel korrekt zu sein, ist die Besetzung notwendig. Auf einigen Systemen ist dies möglicherweise nicht erforderlich (und macOS Sierra ist ein solches System).

Die Newline in printf() ist nicht zu 100% notwendig, aber wenn sie weggelassen wird, folgt die nächste Aufforderung unmittelbar auf den U + 0218 LATIN CAPITAL LETTER S MIT COMMA UNTEN. Es ist besser sicherzustellen, dass die Ausgabe mit einem Zeilenumbruch endet.

4

Der l-Längenbezeichner, der auf einen c-Felddeskriptor angewendet wird, gibt an, dass das entsprechende Argument den Typ wint_t hat (in wchar.h deklariert). In Ihrem Code hat das Argument den Typ int, der identisch sein kann oder nicht. Wenn es tatsächlich nicht das gleiche ist, ist das Verhalten undefiniert. Sie erhalten einen wint_t durch Casting ...

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

; Das ist die sicherste und tragbarste Möglichkeit, eine wint_t-Konstante auszudrücken.

Außerdem gibt es hier eine mögliche Frage nach Zeichensätzen. Das ist eine Frage der Umgebung, in der Ihr Programm läuft, weniger das Programm selbst. Es ist denkbar, dass Ihr Programm tatsächlich das betreffende Zeichen in einer bestimmten Codierung ausgibt, das Terminal, in dem Sie ausgeführt werden, jedoch nicht weiß, wie es gehandhabt werden soll, oder möglicherweise keine Glyphe enthält. Sie sollten in der Lage sein, dies zu testen, indem Sie die Ausgabe in eine Datei umleiten und anschließend den Inhalt der Datei untersuchen (möglicherweise als Binärdatei).

4
John Bollinger

In C ist es nicht erforderlich, dass eine Zeile ohne Zeilenende am Ende gedruckt wird. Versuchen Sie "% lc\n". 

0
gnasher729