8

printf を使用して 2 バイト文字列を 1 バイト文字列にフォーマットする場合:

printf("%ls\n", L"s:\\яшертыHello");   // %ls for a wide string (%s varies meaning depending on the project's unicode settings).

明らかに、一部の文字は ASCII 文字として表現できないため、2 バイト文字が「?」に変換される動作を見たことがあります。マークのキャラクター。ただし、これは特定のキャラクターに依存するようです。上記の printf の場合、出力は次のようになります。

s:\

私は次のようなものが得られることを望んでいました:

s:\??????Hello

残念ながら例を見失ってしまいましたが、1 つの文字列で Unicode 文字が検出されたときに、最初の文字列が「?」に置き換えられたと思います。そして、残りをあきらめました。

私の質問は、ワイド文字列をシングルバイト文字列にフォーマットするとどうなるかということです。ここのドキュメント: http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspxは、「文字は最初の null 文字まで表示される」と述べています。しかし、私はそれを見ていません。これはprintfのバグですか、それとも私が見ている動作はどこかに文書化されていますか?

ご協力いただきありがとうございます。

アップデート

printfを使用する代わりの方法を教えてくれた人々からの回答に感謝します。別の方法に変更するつもりですが、好奇心から、なぜprintfの動作が信頼できる文書化されていないのかに非常に興味があります。それを実装した人が、これを機能させないようにするために道を踏み外したかのように見えます。

4

2 に答える 2

12

私はあなたのコードが動作することを期待しています -- そしてここでは Linux でも動作します -- しかし、それはロケールに依存します。つまり、ロケールを設定する必要があり、そのロケールが使用する文字セットをサポートしている必要があります。ここに私のテストプログラムがあります:

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

int main()
{
    int c;
    char* l = setlocale(LC_ALL, "");
    if (l == NULL) {
        printf("Locale not set\n");
    } else {
        printf("Locale set to %s\n", l);
    }
    printf("%ls\n", L"s:\\яшертыHello");
    return 0;
}

実行トレースは次のとおりです。

$ env LC_ALL=en_US.utf8 ./a.out
Locale set to en_US.utf8
s:\яшертыHello

ロケールが設定されていない、または「C」に設定されていると表示された場合、期待した結果が得られないのは正常です。

編集: Windows の en_US.utf8 に相当するものについては、この質問への回答を参照してください。

于 2012-04-04T08:31:46.353 に答える
5

C++ では、通常、std::stringstreamフォーマットされたテキストを作成するために使用します。また、Windows 関数を使用してエンコーディングを行う独自の演算子も実装しました。

ostream & operator << ( ostream &os, const wchar_t * str )
{
  if ( ( str == 0 ) || ( str[0] == L'\0' ) )
   return os;
  int new_size = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, NULL, NULL, NULL );
  if ( new_size <= 0 )
    return os;
  std::vector<char> buffer(new_size);
  if ( WideCharToMultiByte( CP_UTF8, 0, str, -1, &buffer[0], new_size, NULL, NULL ) > 0 )
    os << &buffer[0];
  return os;
}

このコードは UTF-8 に変換されます。その他の可能性については、次を確認してくださいWideCharToMultiByte

于 2012-04-04T08:26:33.287 に答える