使用isxdigit()时如何处理C中的数组下标警告?

时间:2013-07-07 12:04:25

标签: c arrays compiler-warnings ctype

我在C中有以下代码:

char input[127] = "hello world";

isxdigit(input[0]);

但是我收到了以下警告:

warning: array subscript has type 'char'

是什么原因以及如何解决?

3 个答案:

答案 0 :(得分:8)

原因是在您的C实现中,使用数组查找将isxdigit()实现为宏。

只要您的输入字符串仅包含字符< = 127,您就可以使用强制转换来修复它:

isxdigit ((int)input[0]);

或者,如果您认为演员阵容很丑陋,可以借助良性表达,例如添加0:

isxdigit (0 + input[0]);  /* Avoid cast by using an int-typed expression. */
isxdigit (+input[0]);     /* Same thing using unary plus instead of addition. */

由于C标准要求isxdigit也是一个函数,你也可以调用函数而不是宏:

(isxdigit)(input[0]);

甚至

#undef isxdigit
isxdigit(input[0]);

这不会产生任何警告,因为input[0]被提升为int(假设之前是#include <ctype.h>。)

正如cmaster正确指出的那样,一旦您的char签名并包含负值,这些解决方案就会崩溃。在这种情况下,您必须首先投射到unsigned char(如果需要,则转到int。)

答案 1 :(得分:2)

原因是isxdigit有原型int isxdigit(int)。因此,要删除此警告,您应该明确地将参数强制转换为int

isxdigit((int)input[0]);

答案 2 :(得分:2)

关键是,标准没有定义char类型是否已签名,而是将此决定留给实现。因此(int)(char)128可以评估为128或-128。后者显然不适合数组索引,因为你的编译器注意到了(聪明人,编译器)。

因此,正确的解决方法是投放到unsigned char,而不是投放到int

isxdigit((unsigned char)input[0])

如果你选择其他错误的答案,你最终可能会崩溃utf8字符串! (对于多字节字符,utf8使用大于127的代码。)

编辑:当然,Pascal Cuoq说的是,这样的实现不允许将isxdigit实现为表查找宏,但是,我所说的适用于此编译器警告的任何出现,包括任何查找表你自己实施。非常不幸的是,char的签名没有定义,人们应该更好地了解这个问题并且知道要正确地避免它。