0

ctype.hを定義することは知っていますisdigitが、これは基数10でのみ機能します。数値が特定の基数の数字であるかどうかを確認したいと思いint bます。

Cでこれを行うための最良の方法は何ですか?

編集

私は次の関数を思いついた:

int y_isdigit(char c, int b) {
        static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        static int digitslen = sizeof digits - 1;
        static int lowest = 0;
        int highest = b - 1;

        if(highest >= digitslen)
                return -1; /* can't handle bases above 35 */
        if(b < 1)
                return -2; /* can't handle bases below unary */
        if(b == 1)
                return c == '1'; /* special case */

        int loc = strchr(digits, c);
        return loc >= lowest && loc <= highest;
}

これに対して作成されたバージョンschnaaderを使用することに利点はありますか?(これには、ユーザーの文字セットがASCIIであることに依存しないという追加の利点があるようです。これは、もはやそれほど重要ではありません。)

4

3 に答える 3

4

私は次のようなことを提案します:

// input: char c
if (b <= 10) {
  if ((c >= '0') && (c < ('0' + b))) {
    // is digit
  }
} else if (b <= 36) {
  if ((c >= '0') && (c <= '9')) {
    // is digit
  } else if ((c >= 'A') && (c < 'A' + (b - 10))) {
    // is digit
  }
}

0..9およびA..を使用している場合、これは base 2..36 で動作するはずです (未テスト) Z

別の方法として、ブール値のルックアップ テーブルを使用することもできます。これが最速のチェック方法です。たとえば、256*35 = 8960 バイトのメモリを使用して、基数 2..36 のテーブルを準備できます。この後、isdigitチェックは単純なメモリ読み取りです。

于 2011-02-13T01:05:55.787 に答える
0

従来の基数(8進数または16進数など)を使用strtol()している場合は、変換してエラー状態をチェックするために使用できます。任意の塩基、たとえば塩基99を使用している場合、すぐに使用できるソリューションがない可能性があります。

于 2011-02-13T01:01:03.480 に答える
0

の利点isdigitは、通常、コンパイル時に展開されるマクロであることです。もう 1 つ ありisxdigitます 。

独自の数字の規則に対して同じことをしたい場合は、inlineほぼ同じくらい良い関数を使用できます。

inline
bool isdigit42(char c) {
  switch (c) {
    default: return false;
    case '0': return true;
    case '1': return true;
    .
    .
  }
}

文字が共通の値の範囲内にあるため、コンパイラはどのケースを短縮できるかを最もよく知っています。これがコンパイル時の定数文字で呼び出された場合、これは完全に最適化される必要があります。

于 2011-02-13T08:39:55.687 に答える