Reputation: 9
void emt_card_discount()
{
char emt_card[8];
char*none[5];
int new_total_amt;
printf("\tkey in EMT card number (7 figure) if present or type 'none': \n\t >> ");
scanf_s("%s", &emt_card);
if (strcmp(emt_card,"none") == 0)
{
printf("\tyour seat price is: %.2f\n",total_amt);
}
else
{
new_total_amt = total_amt*0.15;
printf("\tyour seat price is(RM):%.2f\n", new_total_amt);
}
}
This is my code for strcmp.this particular basically functions to provide the user booking the ticket to enter card info to get a special discount..but whenever i get to this part of the code the whole console app crashes..
.
Upvotes: 0
Views: 51
Reputation:
scanf_s()
is not a drop-in replacement for scanf()
. With scanf_s()
, a %s
, %c
or %[
conversion needs two arguments, the second one is the size of the target buffer.
Originally, scanf_s()
(and "friends") is a Microsoft idea, and the Microsoft definition is slightly different from the now standardized scanf_s()
. The Microsoft version defines the size in bytes of type unsigned
, while the C standard defines it in elements of type rsize_t
(which is the same number here, but still incompatible ...).
Correct usage of scanf_s()
would look like this in your code:
char emt_card[8];
[...]
int rc = scanf_s("%s", emt_card, 8U); // microsoft
int rc = scanf_s("%s", emt_card, (rsize_t)8); // standard C
if (rc < 1)
{
// handle error, either EOF or 0 (buffer was too small for input)
}
Note also there's no address-of operator in the call. emt_card
already evaluates to a pointer to the first element (char *
), while &emt_card
would be a pointer to the array (char (*)[8]
). The values are the same, still &emt_card
would have the wrong type, so it's undefined behavior.
The "funny" thing is that you forgot exactly the size which was the reason to introduce scanf_s()
in the first place. scanf("%s", ...)
is alyways a bug because it will overflow any buffer. But there's a way to write this code correctly with just scanf()
as well by using a field width:
int rc = scanf("%7s", emt_card); // read up to 7 bytes, leaving room for the `0` byte
if (rc < 1)
{
// handle error
}
The difference here is that if the input is too long, the scanf()
with a field-width will just stop consuming input, while scanf_s()
with a size given and without field-width would fail the conversion.
I'd personally suggest to never use scanf_s()
and friends because of the incompatible definitions. scanf()
is sufficient if you use field widths. On a side note, scanf()
for interactive input is almost always very problematic, I'd suggest to not use it at all. See my beginners' guide away from scanf()
for more information and alternatives.
Upvotes: 4