Polda18 Polda18 - 1 month ago 11
C Question

Trouble: C Declaration of integer array of unknown size

I need to read unknown amount of various numbers on user's input using

scanf
function. That simply means the number of various integers is determined by the user by sending as many numbers as he can. Note that I read directly the numbers (I have to), as stated in following code:

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;
}
}

...
}


The
int error
is actually a boolean value, but I am lazy to implement boolean library, so I define it as integer :D

However, the problem is elsewhere. Compiler throws me an error:

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


Looks like that C program need to know the allocable size of an array. I already looked into some codes others have shared there to find out basics I need to implement and while searching for the array size issue, I found this question:

C - Declaring an array with an undefined value

However, it does not solve the problem with unknown array size for direct input of unknown amount of numbers. I found nowhere exactly I need to solve. I tried to define maximum size of array to hold up to 999 numbers, but then compiler throws me this exception:

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)
^


Same for every loop used for numbers statistics (total amount, maximum, minimum, odds, evens, positives, negatives, their percentage and average). That means the array is strictly size of 999 numbers with rest of numbers being zeros. I found out a
malloc
function, but do not understand its usage :(

Answer

"I need to read unknown amount of various numbers on user's input using scanf function." is a poor design goal.

Any program that allows an externally interface to input any amount of input without bound is a hacker exploit.

Robust code limits user input to a generous, but sane input amount. Good code will code that upper bound as a constant or macro.

Using scanf() is not the best tool to read user input.
Recommend fgets() to read a line. (Not shown here.)

#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]);
  }
}
Comments