运行strcmp代码时赢得32个控制台应用程序崩溃

时间:2017-11-15 07:12:55

标签: c

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>

1 个答案:

答案 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()