Look at the following code:
printf("Enter name and salary of 'Employee 1':\n");
scanf("I[^\n]%*c,%d", name1,&salary1);
And I input the value as:
Harry Wilson
12000
the next code to echo those values:
puts(name1);
printf("%d",salary1);
The output was:
Harry Wilson
118592
The output of name1
was fine but there was a garbage value inside salary1
.
Suggest me the way to prevent this error!! I want the similar input to employee2 but when I tried to do the same it was not even able to take input.
CodePudding user response:
scanf
reads input and try to match it with the format string passed to scanf
. It will keep on reading as long as the input can match the format string and stop as soon as something doesn't match.
Let's take a close look at your format string.
Format string: I[^\n]%*c,%d
I[^\n] means: Keep reading characters until a newline is found or 49 characters has been read
%*c means: Read the next character an discard it
, means: Read a comma
%d means: Read any number of white spaces (incl. zero) followed by an integer
Your input is `"Harry Wilson\n12000\n" which means:
input is: Harry Wilson\n12000\n
Format I[^\n] will match the Harry Wilson and then
input is: "\n12000\n"
Format %*c will match the first \n and then
input is: "12000\n"
Format , will not match and scanf will return leaving 12000\n in the input stream
So your problem is the comma. Either remove it from the format string or change your input to include a comma at the correct position. Also notice that %*c
is unnecessary as %d
will also read (and discard) the newline before the integer value.
If the "comma" problem is solved a new problem will pop-up. After successful scan of the integer value there will be a \n
in the input stream. This may interfere with any following scanf
calls. Consider adding a space as first character of the format string to remove initial white spaces in the input stream.
Notes:
Consider using fgets
together with sscanf
(or similar parser) instead of scanf
. It will give you a much better control when parsing user input. As an example: Consider what will happen with your current code if a user inputs a 100 character long name.
For both sscanf
and scanf
always check the return value as it tells how many input items that were matched.
CodePudding user response:
You can prevent the error by giving the input in the right syntax:
Harry Wilson
,12000
Gets you successful scanning and echo:
Harry Wilson
12000
This is because the code requires first one "any character" "%c*"
which has to be a newline (because of the ^\n
in the previous "I[^\n]"
) and gets ignored, i.e. not written to any receiving variable. Then it requires a specific ","
.
Doing a check on the return value of scanf()
will help you to get it right.
As long as the return value is not as expected, the scanning did fail and any further scan attempts meet unexpected input which probably makes them fail.
Alternatively you can change the code to match the input.
Either by tinkering with the scanf formatting.
Or, as recommended in the comments already, by reading error-prone input (i.e. anything a human types in) with fgets()
and parsing it with non-destructive sscanf()
attempts. (scanf()
consumes the input...).