【问题标题】:win 32 console app crashes when running strcmp code运行 strcmp 代码时 win32 控制台应用程序崩溃
【发布时间】:2018-04-28 07:47:15
【问题描述】:
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 代码。这个特别的基本功能是为预订机票的用户提供输入卡信息以获得特别折扣。但每当我到达这部分代码时,整个控制台应用程序都会崩溃。

.

【问题讨论】:

  • 只要用户不输入 8 个(或更多)字符,strcmp 调用就没有问题。请尝试创建Minimal, Complete, and Verifiable Example 向我们展示。
  • 顺便提一下,scanf 调用中的&emt_card 在语义上是错误的。它之所以有效,是因为它恰好指向正确的位置,但它是错误的类型("%s" 格式需要一个指向 char 的指针,即char *,但&emt_card 的类型是char (*)[8])。使用&emt_card[0] 或其等效的emt_card
  • 哦,我建议你花点时间去read this scanf_s reference。因为那是导致崩溃的原因,而不是strcmp 调用。
  • 多阅读文档是个好主意:msdn.microsoft.com/de-de/library/w40768et.aspx

标签: c


【解决方案1】:

scanf_s()不是替代scanf()。使用scanf_s()%s%c%[ 转换需要两个参数,第二个是目标缓冲区的大小。

最初,scanf_s()(和“朋友”)是微软的想法,微软的定义与现在标准化的scanf_s()略有不同。 Microsoft 版本以unsigned 类型的bytes 定义大小,而C 标准以rsize_t 类型的elements 定义它(这里的数字相同,但仍然不兼容...)。

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)
}

请注意,调用中没有 address-of 运算符。 emt_card 已经计算出指向第一个元素的指针 (char *),而 &amp;emt_card 将是指向数组的指针 (char (*)[8])。值相同,但 &amp;emt_card 的类型仍然错误,因此是未定义的行为。


“有趣”的事情是你忘记了确切的尺寸,这是首先介绍scanf_s() 的原因。 scanf("%s", ...) 始终是一个错误,因为它会溢出任何缓冲区。但是有一种方法可以使用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() 了解更多信息和替代方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    相关资源
    最近更新 更多