2

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.

3
  • EOF is defined in stdio.h (and is usually -1). On linux, ctrl+d signals EOF, and on windows it's ctrl+z to the process stdin via the shell. did you do one of these ? Commented Jul 29, 2020 at 6:55
  • i actually printed out EOF on my system, and it gave me -1. So i have been using -1 as EOF in my inputs Commented Jul 29, 2020 at 6:57
  • 1
    "I have entered EOF" How? What exactly did you type? Note that if you type a non-number, scanf will return 0 and will leave the offending character in the stream, so it will never return EOF. I suggest == 1 instead of != EOF here. Commented Jul 29, 2020 at 7:20

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.