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.
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.