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);
}
}
这是我的strcmp.this代码的基本功能是为用户提供预订机票输入卡信息以获得特别折扣..但每当我到达这部分代码时整个控制台应用程序崩溃.. < / p>
答案 0 :(得分:4)
scanf_s()
不是scanf()
的替代品。对于scanf_s()
,%s
,%c
或%[
转换需要两个参数,第二个是目标缓冲区的大小。
最初,scanf_s()
(和“朋友”)是微软的想法,微软的定义与现在标准化的scanf_s()
略有不同。 Microsoft版本定义了unsigned
类型的 bytes 的大小,而C标准在类型rsize_t
的元素中定义它(它是相同的)在这里编号,但仍然不相容......)。
scanf_s()
的正确用法在您的代码中如下所示:
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)
}
另请注意,呼叫中没有地址 - 运算符。 emt_card
已经计算到指向第一个元素(char *
)的指针,而&emt_card
将是指向数组的指针(char (*)[8]
)。值是相同的,仍然&emt_card
的类型错误,因此它是未定义的行为。
“有趣”的是,你完全忘记了首先引入scanf_s()
的原因。 scanf("%s", ...)
alyways a bug 因为它会溢出任何缓冲区。但是有一种方法可以使用字段宽度正确地使用scanf()
正确编写此代码:
int rc = scanf("%7s", emt_card); // read up to 7 bytes, leaving room for the `0` byte
if (rc < 1)
{
// handle error
}
这里的区别在于,如果输入太长,具有字段宽度的scanf()
将停止消耗输入,而具有给定大小且没有字段宽度的scanf_s()
将失败转换。
我个人建议永远不要使用scanf_s()
和朋友,因为定义不兼容。如果使用字段宽度,scanf()
就足够了。在旁注中,scanf()
用于交互式输入几乎总是很成问题,我建议根本不使用它。有关更多信息和替代方案,请参阅我的beginners' guide away from scanf()
。