7

wchar_t* 文字列を出力しようとしています。コードは以下のとおりです。

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

char *ascii_ = "中日友好";  //line-1
wchar_t *wchar_ = L"中日友好";  //line-2

int main()
{
    printf("ascii_: %s\n", ascii_);  //line-3
    wprintf(L"wchar_: %s\n", wchar_);  //line-4
    return 0;
}

//Output
ascii_: 中日友好

質問:

  1. 行 1 の char* ポインターに CJK 文字を割り当てるべきではないようですが、行 3 の出力は正しいので、なぜですか? 行 3 の printf() で非 ASCII 文字を取得するにはどうすればよいですか? どういうわけかエンコーディングを知っていますか?

  2. 2 行目と 4 行目のコードは正しいと思いますが、4 行目の出力が得られなかったのはなぜですか?

4

3 に答える 3

9

まず、通常、ソース コードで非 ASCII 文字を使用することはお勧めできません。おそらく起こっているのは、漢字がASCIIで動作するUTF-8としてエンコードされていることです。

さて、なぜ機能しwprintf()ないのかについて。これは、ストリームの向きに関係しています。各ストリームは、ノーマルまたはワイドのいずれかにのみ設定できます。一度設定すると変更できません。初めて使用するときに設定されます。(これは によるASCIIprintfです)。その後、wprintf向きが正しくないため、 は機能しません。

つまり、一度使うと使いprintf()続ける必要がありますprintf()。同様に、 から始めた場合はwprintf()、 を使い続ける必要がありますwprintf()

printf()とを混在させることはできませんwprintf()。(Windows を除く)

編集:

wprintfライン自体が機能しない理由についての質問に答える。これはおそらく、 の UTF-8 形式中日友好が に格納されるようにコードがコンパイルされているためですwchar_。ただし、wchar_t4 バイトの Unicode エンコーディングが必要です。(Windows では 2 バイト)

したがって、私が考えることができる2つのオプションがあります。

  1. 気にしないで、マルチバイトswchar_tに固執してください。charこれは簡単な方法ですが、ユーザーのシステムが中国語のロケールに設定されていない場合は機能しなくなる可能性があります。
  2. を使用wchar_tしますが、Unicode エスケープ シーケンスを使用して漢字をエンコードする必要があります。これにより、明らかにソース コードが読めなくなりますが、ロケールに関係なく、漢字フォントを印刷できる任意のマシンで動作します。
于 2011-09-21T07:42:08.747 に答える
6

行 1 は ascii ではなく、コンパイル時にコンパイラが使用するマルチバイト エンコーディングです。最新のシステムでは、おそらく UTF-8 です。printfエンコーディングがわかりません。バイトを標準出力に送信するだけで、エンコーディングが一致する限り、すべて問題ありません。

注意すべき問題の 1 つは、3 行目と 4 行目で未定義の動作が発生することです。文字ベースの io とワイド文字の io を同じFILE( stdout) に混在させることはできません。最初の操作の後、FILEは「方向」(バイトまたはワイド) を持ち、その後、反対方向の操作を実行しようとすると UB になります。

于 2011-09-21T07:44:28.283 に答える
1

あなたは 1 つのステップを省略しているため、間違った方法で考えています。

ディスク上に、バイトを含む C ファイルがあります。「ASCII」文字列とワイド文字列があります。

ASCII 文字列は、1 行目とまったく同じようにバイトを取得し、それらを出力します。これは、ユーザー側のエンコーディングがプログラマー側のエンコーディングと同じである限り機能します。

ワイド文字列は、最初に指定されたバイトを Unicode コードポイントにデコードし、プログラムに格納します。おそらく、これはあなたの側でうまくいかないでしょう。出力では、ユーザー側のエンコーディングに従って再度エンコードされます。これにより、これらの文字が入力されたときではなく、意図したとおりに出力されることが保証されます。

コンパイラが間違ったエンコーディングを想定しているか、出力ターミナルが間違った方法で設定されています。

于 2011-09-21T07:48:20.687 に答える