C语言中的可变长度数组替代

时间:2019-04-02 10:00:38

标签: c

我有用C语言编写的这段代码,它确实检查以某个数字基数,十进制,八进制,.. etc编写的数字是否正确,这意味着它正在使用属于该特定基数的字符,例如,八进制数字应仅使用字符[0、1、2、3、4、5、6、7],它检查2到36之间的所有基数。

问题是,当我尝试从全部字符中对“基本”字符进行子字符串处理时,它会向我发出警告,提示ISO C90 forbids variable length array 'base_symbols'

int checkNumBase(char *num, int base){

        char all_symbols[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char base_symbols[base];

        int i;
        unsigned int k;    

        for(i = 0; i<base; i++){
            base_symbols[i] = all_symbols[i];
        }


        for(k = 0; k<strlen(num); k++){        
            if(strchr(base_symbols, num[k]) == NULL){

                return 0;
            }
        }
        return 1;
    }

4 个答案:

答案 0 :(得分:4)

一种简单的解决方案是截断字符串

char all_symbols[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";   // length corrected
if(base > 36)
    return 0;
all_symbols[base] = 0;
//.. as before

答案 1 :(得分:3)

  

ISO C90禁止使用可变长度数组'base_symbols'

代码没有任何问题,由于使用的是旧的,过时的编译器,因此会出现错误。您需要获得现代的产品,例如gcc。

请注意,如果正确编译,则较旧的gcc确实支持该语言的较新版本:gcc -std=c11gcc -std=c99,但默认使用“ gnu90”,即C90 +非标准扩展名。较新版本5.0或更高版本默认为“ gnu11”。

例如,-ansi的意思是“给我30岁废话模式”(又称C90)。除非出于反向兼容的原因确实需要C90,否则应使用gcc -std=c17 -pedantic-errors -Wall -Wextra

What is the difference between C, C99, ANSI C and GNU C?

答案 2 :(得分:1)

使用char *index;
然后index = strchr(all_symbols, toupper ( num[k]));查看字符是否在集合中
如果index在集合中,它将具有更大的地址。从较大的地址减去较小的地址以获得肯定的结果
然后if ( index && index - all_symbols < base),然后num [k]对于该基数有效。
toupper()ctype.h

答案 3 :(得分:1)

@WeatherVane(即https://stackoverflow.com/a/55472654/4386427)的解决方案对于OP发布的代码来说是非常好的解决方案。

下面的解决方案显示了一种不使用字符串函数的替代方法。

// Calculate the minimum base that allows use of char c
int requiredBase(char c)
{
  if (c >= '0' && c <= '9') return c - '0' + 1;  // '0' requires base 1, '1' requires base 2, ...
  if (c >= 'A' && c <= 'Z') return c - 'A' + 11; // 'A' requires base 11, 'B'requires base 12, ...
  return INT_MAX;
}

int checkNumBase(char *num, int base){
  while (*num)
  {
    if (requiredBase(*num) > base) return 0;
    ++num;
  }
  return 1;
}