数组下标具有类型'字符' [英] array subscript has type 'char'

查看:253
本文介绍了数组下标具有类型'字符'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code读取命令行参数。如果字符串为1个字符长和一个数字我想用其作为退出值。编译器给了我第二行警告(数组下标有键入'字符')这个错误来自第二部分之后的&放大器;&安培;

 如果(参数[1]!= NULL){
        如果((strlen的(参数[1])== 1)及;&放大器; ISDIGIT(* ARGS [1]))
            出口(((int)的ARGS [1] [0]));
        其他
            出口(0);
    }
}

此外,当我使用不同的编译器,我得到的下一行(出口)两个错误。

  builtin.c:在函数'BUILTIN_COMMAND:
builtin.c:55:警告:函数退出隐式声明
builtin.c:55:警告:内建函数退出不兼容的隐式声明


解决方案

麻烦的是, ISDIGIT()宏接受一个参数,它是一个整数,要么是值EOF或 unsigned char型的值

ISO / IEC 9899:1999(C标ndash的;年老的),§7.4字符处理<&文件ctype.h GT; ,¶1:


  

在所有情况下的参数为 INT ,其值应为
  再presentable为 unsigned char型或应等于宏EOF的值。如果
  说法有任何其他的价值,行为是不确定的。


在你的平台上,字符签订,所以如果你有在0x80..0xFF范围内的角色,它将被作为一个负整数处理。通常的实施 ISDIGIT的()宏是使用参数索引标志位的数组。因此,如果你传递一个字符从范围0x80..0xFF,你是数组开始之前索引,从而导致不​​确定的行为。

 的#define ISDIGIT(X)(_CharType [(X)+1]放大器; _Digit)

您可以安全地使用 ISDIGIT()在以下两种方式:

  INT C =的getchar();如果(ISDIGIT(c))的
    ...

 如果(ISDIGIT((无符号字符)* ARGS [1]))
    ...

在后一种情况下,你知道的值不会EOF。请注意,这是不正常:

  INT C = * ARGS [1];如果(ISDIGIT(C))//未定义的行为,如果* ARGS [1]在范围内0x80..0xFF
    ...


关于功能退出隐含定义警告意味着你不包括<文件stdlib.h方式> 但你应该这样做的。

您也可能会注意到,如果用户给你一个2作为第一个参数的第一个字符,退出状态将是50,而不是2,因为'2'时(通常,在ASCII和UTF-8和8859等)字符code 50( 0 48等)。你会得到 2 (不含引号)使用 * ARGS [1] - '0'作为参数退出()。你并不需要了解它的前pression铸造,但它不会做多大的危害。

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'

解决方案

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.

这篇关于数组下标具有类型'字符'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆