麻烦:C声明未知大小的整数数组

时间:2016-10-22 14:11:39

标签: c arrays compiler-errors

我需要使用scanf函数读取用户输入中未知数量的各种数字。这仅仅意味着用户通过发送尽可能多的数字来确定各种整数的数量。请注意,我直接读取了数字(我必须),如下面的代码中所述:

int main(void)
{
    int numbers[];
    int error = 0;

    int i = 0;
    while(scanf("%i", &numbers[i++]) == 1);

    for(int i = 0; i < sizeof(numbers) - 1; ++i) {
        if(numbers[i] < -10000 || numbers[i] > 10000)
        {
            printf("%i%s", numbers[i], ", ");
        }
        else
        {
            printf("%s", "\b\b\nError: Error: Vstup je mimo interval!\n");
            // Means "Input is out of range!".
            // We have to write exact output to terminal as stated in HW.
            i = sizeof(numbers);
            error = 1;
        }
    }

    ...
}

int error实际上是一个布尔值,但我懒得实现布尔库,所以我把它定义为整数:D

然而,问题出在其他地方。编译器抛出一个错误:

main.c:7:9: error: array size missing in ‘numbers’
     int numbers[];
                ^

看起来C程序需要知道数组的可分配大小。我已经查看了其他人在那里共享的一些代码,以找出我需要实现的基础知识,在搜索数组大小问题时,我发现了这个问题:

C - Declaring an array with an undefined value

但是,对于直接输入未知数量的数据,它无法解决未知数组大小的问题。我找不到我需要解决的问题。我试图定义数组的最大大小以容纳多达999个数字,但是编译器会抛出这个异常:

main.c:50:23: error: iteration 999u invokes undefined behavior [-Werror=aggressive-loop-optimizations]
             if(numbers[j] > 0)
                       ^
main.c:48:9: note: containing loop
         for(int j = 0; j < sizeof(numbers); ++j)
         ^

用于数字统计的每个循环相同(总金额,最大值,最小值,赔率,均数,正数,负数,它们的百分比和平均值)。这意味着数组的大小严格为999,其余数字为零。我找到了malloc函数,但不明白它的用法:(

3 个答案:

答案 0 :(得分:1)

&#34;我需要使用scanf函数读取用户输入中各种数字的未知数量。&#34;是一个糟糕的设计目标。

任何允许外部接口无限制地输入任何输入量的程序都是黑客攻击。

强大的代码将用户输入限制为慷慨但理智的输入量。好的代码会将上限编码为常量或宏。

使用scanf()不是阅读用户输入的最佳工具 建议fgets()阅读。 (此处未显示。)

#include <stdio.h>
#include <ctype.h>

// find the next character without consuming it.
int peek_ch(void) {
  unsigned char ch;
  if (scanf("%c", &ch) == 1) {
    ungetc(ch, stdin);
    return ch;
  }
  return EOF;
}

#define INPUT_N 1000
void foo(void) {
  int input[INPUT_N];
  size_t n = 0;

  // Read 1 _line_ of input using `scanf("%d", ....)` to read one `int` at a time
  for (n = 0; n < INPUT_N; n++) {
    int ch;
    while (((ch = peek_ch()) != '\n') && isspace(ch))
      ;
    // %d consume leading white-space including \n, hence the above code to find it.
    if (scanf("%d", &input[n]) != 1) {
      break;
    }
  }

  // TBD: Add code to handle case when n == N

  for (size_t i = 0; i < n; i++) {
    printf("%zu: %d\n", i, input[i]);
  }
}

答案 1 :(得分:0)

根据评论中的说明,您必须使用malloc动态分配内存,并根据需要使用realloc进行扩展。

以下是一个示例的基本框架:

#define INITIAL_SIZE 1024

#include <stdlib.h>
#include <stdio.h>

int main( void )
{
  size_t arraySize = 0;
  size_t i = 0;

  // initially allocate numbers array
  int *numbers = malloc( sizeof *numbers * INITIAL_SIZE );
  if ( !numbers )
  {
    fprintf( stderr, "Error allocating memory...exiting\n" );
    exit( EXIT_FAILURE );
  }

  arraySize = INITIAL_SIZE;
  int input;
  while ( scanf( "%d", &input ) == 1 )
  { 
    if ( i == arraySize )
    {
      // double the size of the numbers array
      int *tmp = realloc( numbers, sizeof *numbers * (2 * arraySize) );
      if ( !tmp )
      {
        fprintf( stderr, "Could not extend array size...no more inputs allowed\n" );
        break;
      }
      numbers = tmp;
      arraySize *= 2;
    }
    numbers[i++] = input;
  }

  // process numbers
  ...
  // clean up after ourselves
  free( numbers );

答案 2 :(得分:0)

谢谢大家的帮助,我真的很感激。它帮助了我,虽然我真正需要的不是那个解决方案,而是略有不同。如上面的评论所述,我只需要满足作业输入和输出要求。我联系了我的proffessor,他建议我摆脱整数数组,并将while循环内的初始数字列表输出和所有计算进度括起来。然后将百分比和平均值的最终计算包含在if条件测试中,如果没有发生错误,则完成所有最终输出。然而,这不会被标记为解决问题的答案,因为它真的帮助了我很多。但我标记为chux的答案,因为它非常符合逻辑,任何程序都应该通过缓冲区溢出来防止恶意软件攻击。再次感谢大家的帮助,我真的很感激:)