我如何在调试过程中解决这个问题?(0xFEFEFEFE 处未处理的异常)

How I can solve this problem during debugging?(unhandled exception at 0xFEFEFEFE)

scanf_s好像有问题 这是我的代码。

#include <stdio.h>
#include "stack.h"
int main(){ 
    int disk;
    int hanoi[3][9];
    char input[3] = { 0,0,0 };
    int moveDisk;

    for (int i = 0; i < 9; i++) {
        hanoi[0][i] = i + 1;
        hanoi[1][i] = 0;
        hanoi[2][i] = 0;
    }

    printf("Insert the number of disks(1~9): ");
    scanf_s("%d", &disk);

    while (input[0] != 'q') {
        printf("%3c %3c %3c\n", 'A', 'B', 'C');
        for (int i = 0; i < disk; i++) {
            printf("%3d %3d %3d\n", hanoi[0][i], hanoi[1][i], hanoi[2][i]);
        }
        scanf_s("%s", &input); //getting moving disk -- LOCATION OF ERROR
    }
}

我不知道如何解决这个问题

How can I solve this problem during debugging?

运行 你的程序使用调试器一步步来。然后当你得到异常时,你就找到了导致它的行。

重新启动您的程序并转到异常发生的那一行。那就是停止在该行而不执行它。

然后使用调试器,您可以查看所有变量并尝试了解它们的值是否符合您的预期。

这是否回答了您的问题?

顺便说一句:编译器至少应该发出一些警告。你真的应该首先修复这些警告。如果没有警告,请确保已在编译器选项中打开 all 警告。

你引用了这行

scanf_s("%s", &input);

这一行有几处错误:

  1. 您正在将字符串读入字符数组。这是 scanf 正常模式的一个例外,因为您 而不是 需要 &.

  2. 您使用的是半标准 scanf_s,而不是标准 scanfscanf_s 应该是“更安全的”,但为了让它提供安全保证,您也必须以不同于正常 scanf 的方式来称呼它。您必须告诉它要将字符串读入的数组的大小。结合上面的#1,我相信更正确的调用是 scanf_s("%s", input, 3);.

  3. 对于大多数用途,大小为 3 的字符串对于读取用户的一行输入来说太小了。因为在这种情况下,我猜你只是在阅读一个“行”,让自己有机会在程序再次通过它的循环之前点击 RETURN,我想这没关系。

  4. 正如我提到的,scanf_s 不是很标准,所以使用它是一个混合包。优点: 1. 据称它更安全。 2. 某些人(可能包括您的导师)会出于这个原因建议始终使用它。缺点:3. 它完全是标准的(它是标准的可选部分),这意味着并非所有 C 编译器和库都支持它。 4. 它的调用模式必然与正常的大不相同scanf;它不是直接替代品,因此可能会造成混淆。 (我不是说“不要使用 scanf_s”,但您应该意识到它的可疑状态。)

  5. 如果您想在继续之前读取用户输入的一行,并且如果该行可能是“q”或其他内容,scanf(任何种类)可能不是最好的选择。特别是,%s 想要读取一个非空白字符串,所以如果您只是按下 Return 键,它会一直等待。这对您来说可能是问题,也可能不是问题。 (或者这可能不是你现在需要担心的事情;你可能有更大的鱼要炸。)

毫无疑问,您尝试以正常方式使用 scanf(),而 Visual Studio 报告错误,指示您使用 scanf_s()?它不是直接替代品。对于所有 %c%s%[ 格式说明符,您必须提供两个参数 - 接收输入的目标和目标的大小(或严格的元素数量)。

在VS2019中即使是/W1警告级别,也对这种情况的问题给出了明确的解释:

warning C4473: 'scanf_s' : not enough arguments passed for format string
message : placeholders and their parameters expect 2 variadic arguments, but 1 were provided
message : the missing variadic argument 2 is required by format string '%s'
message : this argument is used as a buffer size

不要忽略这些警告,当然也不要全局禁用它们 (/W0)。

所以在这种情况下:

scanf_s("%s", input, sizeof(input) ) ;

再次更严格:

scanf_s("%s", input, sizeof(input)/sizeof(*input) ) ;

但后者实际上只对 wscanf_s (宽字符)是必需的。在这两种情况下,您都可以使用 _countof() 宏,但它是 Microsoft 特定的。

scanf_s("%s", input, _countof(input) ) ;

另请注意 input 之前缺少 &。对于已经是数组或指针的参数,您不需要它。 scanf()也是如此。

虽然有关于使用 scanf_s() 而不是 scanf() 的争论(这本质上更危险),但如果您从标准示例中学习或使用不同的工具链,它只会让生活变得困难。更简单的解决方案就是禁用警告,并了解它是不安全的: