array subscript has type 'char'

旧时模样 提交于 2019-11-28 09:13:49

问题


I have the following code to read an argument from the command line. If the string is 1 character long and a digit I want to use that as the exit value. The compiler gives me a warning on the second line (array subscript has type 'char' ) This error comes from the second part after the "&&" .

    if (args[1] != NULL) {
        if ((strlen(args[1]) == 1) && isdigit(*args[1]))
            exit(((int) args[1][0]));
        else
            exit(0);
    }
}

Also, when I use a different compiler I get two errors on the next line (exit).

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'

回答1:


The trouble is that the isdigit() macro takes an argument which is an integer that is either the value EOF or the value of an unsigned char.

ISO/IEC 9899:1999 (C Standard – old), §7.4 Character handling <ctype.h>, ¶1:

In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.

On your platform, char is signed, so if you have a character in the range 0x80..0xFF, it will be treated as a negative integer. The usual implementation of the isdigit() macros is to use the argument to index into an array of flag bits. Therefore, if you pass a char from the range 0x80..0xFF, you will be indexing before the start of the array, leading to undefined behaviour.

#define isdigit(x)  (_CharType[(x)+1]&_Digit)

You can safely use isdigit() in either of two ways:

int c = getchar();

if (isdigit(c))
    ...

or:

if (isdigit((unsigned char)*args[1]))
    ...

In the latter case, you know that the value won't be EOF. Note that this is not OK:

int c = *args[1];

if (isdigit(c))  // Undefined behaviour if *args[1] in range 0x80..0xFF
    ...

The warning about 'implicit definition of function exit' means you did not include <stdlib.h> but you should have done so.

You might also notice that if the user gives you a 2 as the first character of the first argument, the exit status will be 50, not 2, because '2' is (normally, in ASCII and UTF-8 and 8859-1, etc) character code 50 ('0' is 48, etc). You'd get 2 (no quotes) by using *args[1] - '0' as the argument to exit(). You don't need a cast on that expression, though it won't do much harm.




回答2:


It seems that the compiler you use has a macro for isdigit (and not a function, you wouldn't have a warning if it was the case) that uses the argument as a subscript for an array. That's why isdigit takes an INT as argument, not a char.

One way to remove the warning it to cast your char to int :

isdigit(*args[1]) => isdigit((int)(*args[1]))

The second warning means you want to use the exit function, but it has not been defined yet. Which means you have to do the required #include.

#include <stdlib.h> 

is the standard in c-library to use exit(int) function.

BTW, if this code is in your "main" function, you mustn't check "arg[1] == NULL", which could lead to a segmentation fault if the user didn't provide any argument on the command-line. You must check that the argc value (the int parameter) is greater than 1.




回答3:


It is not completely clear what you want to give as exit code, but probably you want args[1][0] - '0' for the decimal value that the character represents and not the code of the character.

If you do it like that, you'd have the side effect that the type of that expression is int and you wouldn't see the warning.

For exit you probably forgot to include the header file.




回答4:


Try changing

isdigit(*args[1])

to

isdigit(args[1][0])

Your other errors are because you aren't using #include <stdlib.> which defines the exit function.



来源:https://stackoverflow.com/questions/10186219/array-subscript-has-type-char

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!