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