C++には、ある文字が数字であるかどうかを判別するための専用の関数があります。文字の型がナロー文字であるかワイド文字であるか(あるいは他の文字様値であるか)によって、さらにはロケールをどう扱うかによっていくつかの関数を使い分ける必要があります。
isdigit
isdigit関数は最もシンプルな判別関数です。ほとんどの場合はこの関数を使えば事足りるでしょう。下記のサンプルでは、標準入力から1文字読み込んだあと、それが数字であれば “数字” という文字列を標準出力に書き出しています。注意すべきなのは、isdigit関数に渡す実引数の値は0~UCHAR_MAXの範囲でなければならない点です。下記のサンプルでは、unsigned char型にキャストすることで解決しています。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <cctype> int main() { char c; std::cin >> c; if (std::isdigit(static_cast<unsigned char>(c))) { std::cout << "数字" << std::endl; } } |
iswdigit
iswdigit関数はisdigit関数のワイド文字版です。下記のサンプルは、isdigit関数のサンプルをそのままiswdigit関数用に書き換えたものです。引数のキャストが必要ないため、見た目はisdigit関数のサンプルよりすっきりしています。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <cwctype> int main() { wchar_t wc; std::wcin >> wc; if (std::iswdigit(wc)) { std::cout << "数字" << std::endl; } } |
isdigit関数テンプレート
最後は、最も汎用性が高いisdigit関数テンプレートです。この選択は、汎用性は高くなりますが、比較的重い処理になりますので、パフォーマンスが要求される場合には不向きです。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> #include <locale> int main() { char c; std::cin >> c; std::locale loc; if (std::isdigit<char>(c, loc)) { std::cout << "数字" << std::endl; } } |
isdigit関数テンプレートを使うには、明示的に文字型をテンプレート引数として指定しなければなりません。また、第2引数としてロケールを指定する必要があります。
自力で判定する
数字が’0’~’9’だけだと仮定するなら自力で判定することもできます。アルファベットの’a’~’z’や’A’~’Z’の連続性は規格上保証されていません(UTF-8、UTF-16、UTF-32の場合は連続しています)が’0’~’9’が連続していることは保証されています。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <cctype> int main() { char c; std::cin >> c; if ('0' <= c && c <= '9') { std::cout << "数字" << std::endl; } } |
このように自力での判定ロジックをインライン関数にしておくのも悪くないでしょう。