这就是我的尝试:
printf("Please venter first string\n");
char str[127];
scanf_s("%s", &str);
得到了这个例外:
strcmp.exe中的0x0FD2C700(ucrtbased.dll)抛出异常: 0xC0000005:访问冲突写入位置0x00500000。
我也试试这个:
printf("Please venter first string\n");
char str[127];
scanf_s("%d", &str);
在这种情况下没有例外,但我得到了很长的奇怪的字符串。
答案 0 :(得分:4)
让我们首先考虑使用标准scanf
。如果你写
scanf("%s", &str);
这将是不正确的(尽管它可能有效)。将数组传递给函数时,它会衰减到指向第一个元素的指针,这是scanf
所需要的,因此该行应为
scanf("%s", str);
如果要限制输入长度以防止缓冲区溢出,可以像这样(比允许nul
终结符的数组长度少一个)
scanf("%126s", str);
据称更安全的函数scanf_s
要求为每种格式类型%c
以及%s
和%[]
传递一个额外的大小参数,以便下一行(在更正{之后) {1}})
&
缺少该参数,编译器应该发出警告。代码应该是
scanf_s("%s", str);
但即使这样也不够。 scanf_s("%s", str, sizeof str);
函数系列返回成功输入的值的数量。由于用户(甚至我自己)在输入正确的输入(甚至可能是恶意的)方面非常糟糕,因此您必须始终检查数据是否输入正确。如
Xscanf
正如@chux所提到的,最好使用if(scanf_s("%s", str, sizeof str) != 1) {
// inform user and retry etc. etc.
}
获取输入,然后通过各种方式处理它,例如fgets
或sscanf
或strtok
或通过更直接的字符串分析。在这种情况下,使用strsep
,您可以多次尝试处理输入,但使用sscanf
只能获得一次机会。请注意,scanf
和strtok
会修改字符串,因此如果您需要多次尝试对其进行解码,则需要使用副本。
在你的第二个例子中
strsep
你得到“没有异常,只有一个长而奇怪的字符串”,但你应该得到一个编译器警告:
警告C4477:'scanf_s':格式字符串'%d'需要参数 输入'int ',但是可变参数1的类型为'char()[127]'
请注意,您没有将scanf_s("%d", &str);
初始化为“空字符串”,如果您在输入错误后继续处理您想象的好字符串,则可能会发生错误的事情。