So this is my code, and...
#include <stdio.h>
int main()
{
int order, stock;
char credit;
printf("\nEnter order value: ");
scanf("%d", &order);
printf("Enter credit (y/n): ");
scanf("%s", &credit);
printf("Enter stock availabilty: ");
scanf("%d", &stock);
if (order <= stock && credit == 121 || credit == 89)
{
printf("Thank you for ordering from us, the items will be shipped soon.\n\n");
}
else if (credit == 78 || credit == 110)
{
printf("Your credit is insufficient, hence as per company policy we cannot ship your ordered items.\n\n");
}
else if (order > stock && credit == 121 || credit == 89)
{
printf("We're falling short on supply, hence we'll ship the items we have in stock right now.\nThe remaining balance will be shipped as soon as stock arrives.\n\n");
}
else
{
printf("Invalid data.");
}
return 0;
}
... this was my input:
Enter order value: 12
Enter credit (y/n): Y
Enter stock availabilty: 10
The expected output was supposed to be:
We're falling short on supply, hence we'll ship the items we have in stock right now. The remaining balance will be shipped as soon as stock arrives.
However the program printed this:
Thank you for ordering from us, the items will be shipped soon.
Can someone explain me why this happened??
CodePudding user response:
The line
scanf("%s", &credit);
is wrong.
The %s
format specifier expects a pointer to the address where it should write the input as a string. When doing this, you must ensure that there is sufficient memory in that location to write the string.
However, at the specified memory location, there is only space for a single character, because with the line
char credit;
you only declared a single character.
For storing the string "Y"
, you need at least space for two characters, one for the character Y
and one for the terminating null characer of the string. In C, strings always have a terminating null character at the end.
Of course, it would be possible to could solve this problem by adding space for a second character, and limiting the number of matched characters to 1, in order to ensure that there will be enough space for storing the string.
char credit[2];
[...]
scanf( "%1s", credit );
However, I do not recommend this solution. Instead, I recommend that you use the %c
format specifier instead of the %s
format specifier. The %s
format specifier is intended for entire strings, whereas the %c
format specifier is intended for individual characters.
Therefore, this solution would probably be better:
char credit;
[...]
scanf( "%c", &credit );
However, this solution has one problem. The previous function call to scanf
scanf( "%d", &order );
will not have consumed the entire previous line, but will only consume as many characters as possible to match the number. All characters that are not part of the number, including the newline character, will be left on the input stream.
Therefore, if you call
scanf( "%c", &credit );
afterwards, the %c
format specifier will probably match the newline character, instead of the Y
in the next line. See this question for further information on this problem:
scanf() leaves the newline character in the buffer
In order to solve this problem, you can instruct scanf
to first discard all whitespace characters (newline characters are whitespace characters), before attempting to match the %c
format specifier:
scanf( " %c", &credit );
Another way of solving the problem of leftover characters would be to use fgets
instead of scanf
. This solution has the advantage that the behavior of that function is more intuitive, as it normally reads exactly one line of input per function call. In contrast to scanf
, it does not normally leave leftovers of a line on the input stream. See this guide for further information: