wchar_t
()を()'9'
の形式の数字に変換するにはどうすればよいですか?int
9
peek
数字かどうかを確認する次のコードがあります。
if (iswdigit(peek)) {
// store peek as numeric
}
減算することはできます'0'
か、それとも心配すべきUnicodeの詳細がありますか?
関数の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);
}
質問がちょうど'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;
}
このようにすると:
UnicodeData.txt
Unicodeコンソーシアムからファイルをダウンロードすることをお勧めします
(「 UncodeCharacter Database」-このページには、Unicodeデータファイルとその中で使用されているエンコーディングの説明の両方へのリンクがあります)。最後に、ストリームで使用される変換はローマ数字のみを使用するように定義されているため、ostringstream
および
istringstream
(これにはを含む)に基づくソリューションは機能しないことに注意してください。boost::lexical_cast
(一方、コードをローマ数字だけに制限するのが合理的かもしれません。その場合、テストはif ( wch >= L'0' && wch <= L'9' )
になり、変換は単純に減算することによって行われますL'0'
—常にコンパイラのワイド文字定数のネイティブエンコーディングを想定していますはUnicodeです(VC++とg++の両方の場合)。または、ロケールが「C」(またはUnixマシンでは「Posix」)であることを確認してください。
編集:私は言及するのを忘れました:あなたが深刻なUnicodeプログラミングをしているなら、あなたはICUを調べるべきです。Unicodeを正しく処理することは非常に簡単ではなく、多くの機能がすでに実装されています。
あなたが使用することができますboost::lexical_cast
:
const wchar_t c = '9';
int n = boost::lexical_cast<int>( c );
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'減算がおそらく期待どおりに機能しないことを意味します。
ほとんどの場合、「0」のコードを引くだけです。
ただし、Unicode数値に関するウィキペディアの記事には、10進数が23の別々のブロック(アラビア語で2回を含む)で表されていると記載されています。
それについて心配していない場合は、「0」のコードを引くだけです。