【问题标题】:Array subscript has type ‘char’ [-Wchar-subscripts]数组下标的类型为“char”[-Wchar-subscripts]
【发布时间】:2013-11-07 22:58:43
【问题描述】:

我正在尝试在帮助函数下方的帮助下删除前导/尾随空格字符。 编译时我收到警告:数组下标的类型为'char' [-Wchar-subscripts] 如何摆脱这个消息。

  char *removeSpace(char *str )
  {
     char *end;

     // Trim leading space
     while(isspace(*str)) 
     str++;

    if(*str == 0)  // All spaces?
    return str;

   // Trim trailing space
   end = str + strlen(str) - 1;
   while(end > str && isspace(*end)) end--;

   // Write new null terminator
   *(end+1) = 0;

   return str;
 }

【问题讨论】:

  • 该错误并非来自您发布的代码。
  • 当您收到警告或错误时,编译器会帮助您告诉您是哪个行号产生了问题。大多数情况下,编译器都能做到这一点。您有责任转到该行号并查看代码。如果您不明白,您需要向我们指出哪一行有问题,并提供所有相关代码,以帮助我们向您解释。
  • 也许您使用isspace 的变体,它是一个索引数组的宏?如果是这样,这是一个糟糕的实现。
  • 顺便说一句,end > str 是不需要的,因为你知道 isspace(*str) 是假的。

标签: c


【解决方案1】:

警告可能是因为您将char 传递给isspace() 宏。 isspace() 的实现可能是通过数组索引。 (isspace() 宏的参数被定义为一个 整数,其值可以放入 unsignedchar)。

我刚刚查看了 GNU libc 中的 ctype.h,虽然有一堆复杂的宏和函数,但在 isspace() 的定义中的某处有一个被索引的数组。

查看isspace((unsigned char) *str) 是否消除了警告。

【讨论】:

  • 是的,确实消除了警告。
【解决方案2】:

您发布的代码根本没有任何数组下标,但该错误是由以下代码引起的:

int array[256];
char c = ...;
array[c] = ...;

array[c] 行很可能是一个错误,因为char 类型可以是有符号或无符号的——这取决于编译器。如果 char 已签名,则 c 可能为负数,在这种情况下,访问负数数组索引会导致未定义行为。

解决方法是确保您从不使用 char 变量作为数组索引 - 始终首先转换为无符号类型,并始终确保您的值在范围内。如果您在一个 8 位 chars 的系统上运行(即 CHAR_BIT 为 8),那么 256 元素数组将始终能够存储所有可能的 unsigned char 值,并且您可以省略边界检查:

int array[256];
char c = ...;
array[(unsigned char)c] = ...;  // Always ok, if CHAR_BIT <= 8

【讨论】:

  • 当然最好总是 声明数组索引值作为unsigned类型!
  • 其实isspace()宏可以用数组来实现。
【解决方案3】:

您可以使用该编译器标志禁用此警告:

-Wno-char-subscripts

【讨论】:

  • 只有在您完全了解警告的目的之后,才适合禁用警告。
【解决方案4】:

-Wchar-subscripts : 如果数组下标的类型为 char 则发出警告

产生上述警告的示例代码。

#include<stdio.h>
int main()
{
int a[10]; //or even char a[10];
char c=5;
printf("%d",a[c]); //you might used like this in your code array with character subscript
return 0;
} 

在您的代码中(未发布),您可能会像上面一样使用 char 下标。

在您的代码中产生 -Wchar-subscripts 警告的 main 示例:

int main()
{
        char c=20;
        char   s[c];
        printf("Enter string:");
        fgets(s,sizeof(s),stdin);
        printf("String before removal of spaces : \n%s",s);
        printf("%c",s[c]);  //accessing s[c],array element with char subscript or else any Expression you might used this
        printf("test text\n");
        strcpy(s,removeSpace(s));
        printf("String after removal of spaces : \n%s",s);
        printf("test text\n");
        return 0;
}

但是在您发布的代码中没有 char subscript 。通过添加 main 来测试你的代码。没有重现任何警告或错误。我使用 gcc -Wall -Werror file.c 进行了编译。

如果您仍然不明白,请发布您的整个代码。

没有产生任何警告和错误的测试代码:

#include<stdio.h>
#include<string.h>
#include <ctype.h> //included this to use isspace
char *removeSpace(char *);

char *removeSpace(char *str )
  {
     char *end;

     // Trim leading space
     while(isspace(*str))
     str++;

    if(*str == 0)  // All spaces?
    return str;

   // Trim trailing space
   end = str + strlen(str) - 1;
   while(end > str && isspace(*end)) end--;

   // Write new null terminator
   *(end+1) = 0;

   return str;
 }


int main()
{
        char  s[20];
        printf("Enter string:");
        fgets(s,sizeof(s),stdin);
        printf("String before removal of spaces : \n%s",s);
        printf("test text\n");
        strcpy(s,removeSpace(s));
        printf("String after removal of spaces : \n%s",s);
        printf("test text\n");
        return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 2021-08-06
    相关资源
    最近更新 更多