Trying to use scanf to check i have the right amount of inputs ( in this case 2), and the code works fine, but if i put in 1 input it just keeps waiting for a second, and if i put in 3 it just discards the 3rd, nothing i do will ever return the error message. Have searched for an answer, but not found anything i could use, the reason i ask is the text book i am using for this subject has the code exactly the same as i have it here ( i copied out a different example for int_swap word for word, and it doesn't seem to work either? Any ideas? Sorry if this is a stupid or easy question.
#include <stdlib.h>
#include <stdio.h>
void int_sort2(int*, int*);
int
main(int argc, char* argv[])
{
int x, y;
printf("Please enter 2 numbers : ");
if(scanf("%d%d", &x, &y) != 2)
{
printf("Error in numbers entered\n");
exit(EXIT_FAILURE);
}
printf("The original order was %d, %d\n", x, y);
int_sort2(&x, &y);
printf("The sorted order is : %d, %d\n", x,y);
return 0;
}
void
int_sort2(int *x, int *y)
{
if(*y < *x)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
return;
}
As the documentation of scanf
said that
On success, the function returns the number of items of the argument list successfully filled.
It will return the number of items that was loaded not the number of item that you just inputted.
solution:
count the number of ints before you scanf it.
if i put in 1 input it just keeps waiting for a second
At that point, if the input stream ends (like the end of data from a pipe or by pressing platform specific keys to terminate console input), you will get the error message.
Let's say you built an executable called mytest
from the above code. If you use:
echo 20 | ./mytest
you should get the error message.
if i put in 3 it just discards the 3rd, nothing i do will ever return the error message.
Your scanf
line looks for two integers. If it find them, it returns them. If there are more data in the stream, it is not responsible for dealing with them. Hence, you don't get any error message if there are more than 2 numbers in the input.
i copied out a different example for int_swap word for word, and it doesn't seem to work either? Any ideas?
Your version of int_swap
seems to be fine.
Okay, so you have to understand how scanf is actually behaving internally to understand why it's not acting properly.
From the scanf man page:
RETURN VALUE
These functions return the number of input items
successfully matched and assigned, which 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 indicate the error.
let's say you have:
#include <stdio.h>
int main() {
int x, y, rv;
rv = scanf("%d %d", &x, &y);
if(rv < 2) {
fprintf(stderr, "Woops not enough arguments available on input\n");
return -1;
}
printf("X was %d and Y was %d\n", X, Y);
return 0;
}
The reason you think that you are experiencing misbehavior is because you are misunderstanding how buffered input works, and you are confused about the fact that scanf will actually care about any input beyond the end of its format string.
The end of format string does NOT indicate end of input or closing of stdin. So in code above if you want to induce an error, run the program and if you are using some *nix just type CTRL+D to indicate EOF on stdin
, and it will trigger the if
statement provided you haven't entered 2 numbers.
An Aside: Swapping two integers without the use of a temp variable
void swap(int *a, int *b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
Or you can define a macro:
#define swap(a, b) do { a ^= b; b ^= a; a ^= b; } while(0)