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..9A.. ,这应该适用于 base 2..36(未经测试) Z

另一种方法是使用布尔查找表,这是最快的检查方法。例如,您可以为基数 2..36 准备表,使用 256*35 = 8960 字节的内存,之后isdigit检查是简单的内存读取。

于 2011-02-13T01:05:55.787 回答
0

如果您使用的是传统基数(例如八进制或十六进制),您可以使用它strtol()来转换和检查错误情况。如果您使用任意基数,例如基数 99,则可能没有开箱即用的解决方案。

于 2011-02-13T01:01:03.480 回答
0

的优点isdigit是它通常是一个在编译时扩展的宏。还有一个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 回答