10

wchar_t()を()'9'の形式の数字に変換するにはどうすればよいですか?int9

peek数字かどうかを確認する次のコードがあります。

if (iswdigit(peek)) {
    // store peek as numeric
}

減算することはできます'0'か、それとも心配すべきUnicodeの詳細がありますか?

4

5 に答える 5

6

関数のatoiクラスを調べます:http://msdn.microsoft.com/en-us/library/hc25t012 (v = vs.71).aspx

特に_wtoi(const wchar_t *string);あなたが探しているもののようです。ただし、適切にnullで終了していることを確認する必要がwchar_tあるため、次のようにしてみてください。

if (iswdigit(peek)) {
    // store peek as numeric
    wchar_t s[2];
    s[0] = peek;
    s[1] = 0;
    int numeric_peek = _wtoi(s);
}
于 2011-05-20T07:36:47.310 に答える
6

質問がちょうど'9'(またはローマ数字の1つ)に関係する場合'0'は、減算するだけが正しい解決策です。ただし、ゼロ以外を返すものに関心がある場合iswdigitは、問題がはるかに複雑になる可能性があります。標準ではiswdigit、引数が「[現在のローカルの] 10進数のワイド文字コード」の場合、ゼロ以外の値を返すとされています。これはあいまいであり、意味を正確に定義するのはロケールに任されています。「C」ロケールまたは「Posix」ロケールでは、少なくとも「Posix」標準は、0から9までのローマ数字のみが10進数と見なされることを保証します(私が正しく理解している場合)。 「C」または「Posix」ロケール。「0」を引くだけで機能するはずです。

おそらく、Unicodeロケールでは、これは一般的なカテゴリを持つ任意の文字になりますNd。これらはたくさんあります。最も安全な解決策は、次のようなものを作成することです(ここでは静的な有効期間を持つ変数):

wchar_t const* const digitTables[] =
{
    L"0123456789",
    L"\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669",
    // ...
};

//!     \return
//!         wch as a numeric digit, or -1 if it is not a digit
int asNumeric( wchar_t wch )
{
    int result = -1;
    for ( wchar_t const* const* p = std::begin( digitTables );
            p != std::end( digitTables ) && result == -1;
            ++ p ) {
        wchar_t const* q = std::find( *p, *p + 10, wch );
        if ( q != *p + 10 ) {
            result = q - *p;
    }
    return result;
}

このようにすると:

  1. UnicodeData.txtUnicodeコンソーシアムからファイルをダウンロードすることをお勧めします (「 UncodeCharacter Database」-このページには、Unicodeデータファイルとその中で使用されているエンコーディングの説明の両方へのリンクがあります)。
  2. 情報を自動的に抽出するために、このファイルの単純なパーサーを作成する可能性があります(たとえば、新しいバージョンのUnicodeがある場合)。このファイルは、単純なプログラムによる解析用に設計されています。

最後に、ストリームで使用される変換はローマ数字のみを使用するように定義されているため、ostringstreamおよび istringstream(これにはを含む)に基づくソリューションは機能しないことに注意してください。boost::lexical_cast(一方、コードをローマ数字だけに制限するのが合理的かもしれません。その場合、テストはif ( wch >= L'0' && wch <= L'9' )になり、変換は単純に減算することによって行われますL'0'—常にコンパイラのワイド文字定数のネイティブエンコーディングを想定していますはUnicodeです(VC++とg++の両方の場合)。または、ロケールが「C」(またはUnixマシンでは「Posix」)であることを確認してください。

編集:私は言及するのを忘れました:あなたが深刻なUnicodeプログラミングをしているなら、あなたはICUを調べるべきです。Unicodeを正しく処理することは非常に簡単ではなく、多くの機能がすでに実装されています。

于 2011-05-20T08:29:07.297 に答える
1

あなたが使用することができますboost::lexical_cast

const wchar_t c = '9';
int n = boost::lexical_cast<int>( c );
于 2011-05-20T07:40:30.367 に答える
1

MSDNのドキュメントにも関わらず、簡単なテストでは、レンジャーL'0'-L'9'だけがtrueを返すわけではないことが示唆されています。

for(wchar_t i = 0; i < 0xFFFF; ++i)
{
    if (iswdigit(i))
    {
        wprintf(L"%d : %c\n", i, i);
    }
}

これは、L'0'減算がおそらく期待どおりに機能しないことを意味します。

于 2011-05-20T07:55:33.603 に答える
0

ほとんどの場合、「0」のコードを引くだけです。

ただし、Unicode数値に関するウィキペディアの記事には、10進数が23の別々のブロック(アラビア語で2回を含む)で表されていると記載されています。

それについて心配していない場合は、「0」のコードを引くだけです。

于 2011-05-20T07:36:50.157 に答える