web-dev-qa-db-ja.com

printfでUnicode文字を印刷する

対応する10進値をprintfに渡して、Șを出力しようとしています。出力はまったくありません。コードが機能しないのはなぜですか?

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

MacOS Sierra10.12.2とGCC6.3.0で、このプログラムを実行すると(_mb37.c_から_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;
}
_

出力は次のとおりです。

_$ ./mb37
Ș
$
_

それが望ましい出力だと私は信じています。 setlocale()行が削除されると、出力はまったく生成されません。改行も生成されません。使用されるロケールは_en_US.UTF-8_です。私の端末はUTF-8も処理します。ロケール名は、setlocale() —通常の文字列からの戻り値をキャプチャして出力することによって検出されます。

_wint_t_キャストはセミオプションです。キャストまたは_<wchar.h>_ヘッダーのない64ビットコンパイルでも同じ出力が生成されることがありますが、_wint_t_がintと同じであるというわずかな偶然があります。それにはある程度の追跡が必要です。 _wint_t_は___darwin_wint_t_として定義され、___darwin_ct_rune_t_はintとして定義されます。移植可能に正しくするには、キャストが必要です。一部のシステムでは、それは必要ないかもしれません(そしてmacOSSierraはそのようなシステムの1つです)。

printf()の改行は100%必要ではありませんが、省略した場合、次のプロンプトは、以下のカンマ付きのU +0218ラテン大文字の直後に続きます。出力が改行で終わるようにすることをお勧めします。

4

lフィールド記述子に適用されるc長さ指定子は、対応する引数がタイプwint_twchar.hで宣言)であることを示します。コードでは、引数の型はintであり、同じである場合とそうでない場合があります。それが実際に同じでない場合、動作は定義されていません。キャストすることでwint_tを取得できます...

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

;これは、wint_t定数を表現するための最も安全で移植性の高い方法です。

さらに、ここには文字セットの潜在的な問題があります。これは、プログラム自体ではなく、プログラムが実行される環境の問題です。あなたのプログラムが実際に問題の文字を何らかのエンコーディングで出力することは考えられますが、あなたが実行している端末はそれを処理する方法を知らないか、あるいは単にそれのグリフを持っていません。出力をファイルにリダイレクトし、後でファイルの内容(おそらくバイナリファイルとして)を調べることで、それをテストできるはずです。

4
John Bollinger

Cでは、末尾に改行文字がない行を印刷する必要はありません。 「%lc\n」を試してください。

0
gnasher729