# Thread: Need help error capturing using scanf

1. ## Need help error capturing using scanf

I would greatly appreciate if someone could help with the following:

I am attempting to read in a fraction using scanf and store the numerator and denominator as integers. The following code that I have written captures most errors however if for example 1/2/3 is entered then I believed that scanf would not return 3 and therefore be caught. Not the case it still returns 3! Does anyone have any ideas?

Paul

do
{
errorFlag=0;
printf("\n\nEnter a fraction:> ");
fflush(stdin);
x=scanf(" %i %c %i", &num1, &slash, &denom1);
if (x!=3 || slash!=47)
{
printf("Input must be of form A/B where A and B are both integers.");
errorFlag=1;
}
if (denom1==0)
{
printf("\nDenominator cannot be zero.");
errorFlag=1;
}
}
while(errorFlag==1);

2. First of all, I don't know why at all you would want to do:

x=scanf(" %i %c %i", &num1, &slash, &denom1);

You don't need to store the slash. So you would better be off doing:

x = scanf("%d/%d", &num1, &denom1);

(formatted for int is %d not %i) You want to trap to see if they wrote something else? Because you can just dismiss it without trapping. Understand?

--Garfield

3. Garfield

Thanks for the response. As you can tell I am still pretty new to C - I didn't realise you could check for the slash without needing to store it.

I know I could dismiss anything input after A/B but lets say someone meant to put 3/15 and actually put 3/1/5 then this would be seen by my code as 3/1 and an incorrect result would be given. Am I being too strict with the workflow do you think??? :-) If it's too complex to check for this then I'd leave it.

(BTW all the books I have seem to make no distinction between %d and %i - am I missing something critical?)

4. Due to the fact that when you scan the input stream for just %d/%d, that is "restricted" scanning. You could scan a whole string in and then read the string to see the user input. That will take more steps, though. It's up to you.

5. The best answer is to forget using scanf, and do this

Code:
```char buff[100];
fgets( buff, sizeof(buff), stdin );```
This does two things
1) it removes the need for any fflush(stdin), which doesn't work anyway (despite local appearances that it might)
2) you now have the whole line in memory

The problem with scanf, is that it is a one-way trip - if you get stuck, there's no going back except to ask the user to retype it all.

Now if you want to, you could do this
Code:
```int last;
x = sscanf( buff, "%d/%d%n", &num1, &denom1,&last);```
sscanf is like scanf, except it works on in-memory strings - the advantage being, you can have several goes at decoding it, and you need not even use sscanf to decode it (you could do your own thing)

A note about %n - this tells you where in the string you got to
buff[last] is the index of the first unscanned character in buff. Also note, that x would be still 2 (not 3 as you might expect)

> BTW all the books I have seem to make no distinction between %d and %i
They're wrong then
If you have %d, then you must type 10, to read in decimal 10
If you have %i, you can type 10, 0xa or 012, as the decimal, hexadecimal or octal versions of decimal 10.