我如何在调试过程中解决这个问题?(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);
这一行有几处错误:
您正在将字符串读入字符数组。这是 scanf 正常模式的一个例外,因为您 而不是 需要 &
.
您使用的是半标准 scanf_s
,而不是标准 scanf
。 scanf_s
应该是“更安全的”,但为了让它提供安全保证,您也必须以不同于正常 scanf
的方式来称呼它。您必须告诉它要将字符串读入的数组的大小。结合上面的#1,我相信更正确的调用是 scanf_s("%s", input, 3);
.
对于大多数用途,大小为 3 的字符串对于读取用户的一行输入来说太小了。因为在这种情况下,我猜你只是在阅读一个“行”,让自己有机会在程序再次通过它的循环之前点击 RETURN,我想这没关系。
正如我提到的,scanf_s
不是很标准,所以使用它是一个混合包。优点: 1. 据称它更安全。 2. 某些人(可能包括您的导师)会出于这个原因建议始终使用它。缺点:3. 它完全是标准的(它是标准的可选部分),这意味着并非所有 C 编译器和库都支持它。 4. 它的调用模式必然与正常的大不相同scanf
;它不是直接替代品,因此可能会造成混淆。 (我不是说“不要使用 scanf_s
”,但您应该意识到它的可疑状态。)
如果您想在继续之前读取用户输入的一行,并且如果该行可能是“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()
的争论(这本质上更危险),但如果您从标准示例中学习或使用不同的工具链,它只会让生活变得困难。更简单的解决方案就是禁用警告,并了解它是不安全的:
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);
这一行有几处错误:
您正在将字符串读入字符数组。这是 scanf 正常模式的一个例外,因为您 而不是 需要
&
.您使用的是半标准
scanf_s
,而不是标准scanf
。scanf_s
应该是“更安全的”,但为了让它提供安全保证,您也必须以不同于正常scanf
的方式来称呼它。您必须告诉它要将字符串读入的数组的大小。结合上面的#1,我相信更正确的调用是scanf_s("%s", input, 3);
.对于大多数用途,大小为 3 的字符串对于读取用户的一行输入来说太小了。因为在这种情况下,我猜你只是在阅读一个“行”,让自己有机会在程序再次通过它的循环之前点击 RETURN,我想这没关系。
正如我提到的,
scanf_s
不是很标准,所以使用它是一个混合包。优点: 1. 据称它更安全。 2. 某些人(可能包括您的导师)会出于这个原因建议始终使用它。缺点:3. 它完全是标准的(它是标准的可选部分),这意味着并非所有 C 编译器和库都支持它。 4. 它的调用模式必然与正常的大不相同scanf
;它不是直接替代品,因此可能会造成混淆。 (我不是说“不要使用scanf_s
”,但您应该意识到它的可疑状态。)如果您想在继续之前读取用户输入的一行,并且如果该行可能是“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()
的争论(这本质上更危险),但如果您从标准示例中学习或使用不同的工具链,它只会让生活变得困难。更简单的解决方案就是禁用警告,并了解它是不安全的: