xiaozaiz
xiaozaiz

Reputation: 69

Reading user input into array up to its maximum size

Assume max_size of array is 100, I am trying to scanf user input into the array until EOF is entered. When the function detects EOF, scanf stops and returns the number of elements entered so far.

int read_ints_from_stdin(int array[], int max_array_size) { 
    int i = 0, num;
    while ((scanf("%d", &num) != EOF) && i < max_array_size) {
        array[i++] = num;
        printf("value of i is: %d \n", i);
    }
    return i;
}

However, i keeps on increasing until max_array_size and the function always returns 100 even though I have entered EOF. Can anyone help me out on this?

Edit: apparently, I'm storing random values into my array rather than what the user is inputting.

Upvotes: 2

Views: 167

Answers (2)

Marco Bonelli
Marco Bonelli

Reputation: 69276

First of all, let's make one thing clear: there is no such thing as an EOF character. EOF does not exist as a character, you will not be able to "enter EOF" or "read EOF". EOF is just an arbitrary integer constant, a library defined abstraction that is used by library functions to signal that the end of file has been reached or that an error occurred. That's it.

If you want to make sure what you're doing makes sense, have a look at the scanf manual page:

RETURN VALUE
   On success, these functions return the number of input items
   successfully matched and assigned; this can be fewer than provided
   for, or even zero, in the event of an early matching failure.

   The value EOF is returned if the end of input is reached before
   either the first successful conversion or a matching failure occurs.
   EOF is also returned if a read error occurs, in which case the error
   indicator for the stream (see ferror(3)) is set, and errno is set to
   indicate the error.

Reading the above, it's clear that scanf does not only return EOF when the end of file is reached. Furthermore, scanf can return 0 if no error occurs but no match is made, and you should stop reading in this case too.

What you want to do in this case is to use a simple for loop, and check if scanf returned 1, which is the only value that is acceptable for you. If not, either the end of file was reached, an error occurred, or the input did not match the format string: check the error and act accordingly. Do not squash all the error checking logic inside a while condition, that's just confusing and hard to get right.

Here's a working example, error checking is probably even more than you actually need, but it's just to make things clear.

size_t read_ints_from_stdin(int array[], size_t max_array_size) { 
    size_t i;

    for (i = 0; i < max_array_size; i++) {
        int res = scanf("%d", &array[i]);
        
        if (res != 1) {
            if (res == EOF) {
                if (feof(stdin)) {
                    // End of file reached, not an error.
                } else {
                    // Real error, print that out to stderr.
                    perror("scanf failed"); 
                }
            } else {
                // Input matching failure.
                fputs("Input does not match requested format.\n", stderr);
            }
            
            break;
        }
    }
    
    return i;
}

Also, notice the usage of size_t where needed instead of int. You don't want to end up in errors arising from negative values when dealing with sizes or indexes.

Upvotes: 3

Sai Raman Kilambi
Sai Raman Kilambi

Reputation: 888

You need to modify your while loop condition to something like this:

int read_ints_from_stdin(int array[], int max_array_size) { 
    int i = 0, num;
    while ( i < max_array_size) {
        scanf("%d", &num);
        if(num == EOF) break;
        array[i++] = num;
        printf("value of i is: %d \n", i);
    }
    return i;
}

You should compare the value of number with EOF but not the value returned by scanf.This is because, scanf returns the number of successful inputs assigned. In your code, at every iteration, scanf always retuns 1(because the value is assigned to num), which is later compared with EOF(which expands to -1)

Upvotes: 1

Related Questions