数组下标的类型为’char’
我有以下代码从命令行读取参数。 如果字符串长度为1个字符,并且我想将其用作退出值。 编译器在第二行给出了警告(数组下标的类型为’char’)此错误来自“&&”之后的第二部分。
if (args[1] != NULL) { if ((strlen(args[1]) == 1) && isdigit(*args[1])) exit(((int) args[1][0])); else exit(0); } }
此外,当我使用不同的编译器时,我在下一行(退出)上得到两个错误。
builtin.c: In function 'builtin_command': builtin.c:55: warning: implicit declaration of function 'exit' builtin.c:55: warning: incompatible implicit declaration of built-in function 'exit'
问题是isdigit()
宏接受一个参数,该参数是一个整数,它是值EOF或unsigned char
的值。
ISO / IEC 9899:1999(C标准 – 旧),§7.4字符处理
,¶1:
在所有情况下,参数都是一个
int
,其值应表示为unsigned char
或者等于宏EOF的值。 如果参数具有任何其他值,则行为未定义。
在您的平台上, char
已签名,因此如果您的字符在0x80..0xFF范围内,则将其视为负整数。 isdigit()
宏的通常实现是使用参数索引到标志位数组。 因此,如果从0x80..0xFF范围传递char
,则将在数组开始之前编制索引,从而导致未定义的行为。
#define isdigit(x) (_CharType[(x)+1]&_Digit)
您可以通过以下两种方式之一安全地使用isdigit()
:
int c = getchar(); if (isdigit(c)) ...
要么:
if (isdigit((unsigned char)*args[1])) ...
在后一种情况下,您知道该值不是EOF。 请注意,这不行:
int c = *args[1]; if (isdigit(c)) // Undefined behaviour if *args[1] in range 0x80..0xFF ...
关于’函数退出的隐式定义’的警告意味着你没有包含
但是你应该这样做。
你可能还会注意到,如果用户给你一个2作为第一个参数的第一个字符,退出状态将是50而不是2,因为'2'
是(通常,在ASCII和UTF-8和8859-1中,等)字符代码50( '0'
是48等)。 通过使用*args[1] - '0'
作为exit()
的参数,你得到2
(没有引号exit()
。 你不需要对该表达式进行强制转换,但它不会造成太大伤害。
您使用的编译器似乎有一个用于isdigit的宏(而不是函数,如果是这种情况,则不会发出警告)将该参数用作数组的下标。 这就是为什么isdigit将INT作为参数,而不是char。
删除警告的一种方法是将char转换为int:
isdigit(*args[1]) => isdigit((int)(*args[1]))
第二个警告意味着您要使用退出function,但尚未定义。 这意味着您必须执行所需的#include。
#include
是使用exit(int)函数的c库中的标准。
顺便说一句,如果此代码在您的“主”函数中,则不能检查“arg [1] == NULL”,如果用户未在命令行上提供任何参数,则可能导致分段错误。 您必须检查argc值(int参数)是否大于1。
你想要作为退出代码提供什么并不完全清楚,但是你可能想要args[1][0] - '0'
代表字符所代表的十进制值,而不是字符的代码。
如果你这样做,你会产生副作用,即该表达式的类型是int
,你不会看到警告。
exit
您可能忘记包含头文件。
尝试改变
isdigit(*args[1])
至
isdigit(args[1][0])
您的其他错误是因为您没有使用定义exit
函数的#include
。