我开始学习在C中输入字符串。在下面的源代码中,我得到一个长度为5的字符数组。
#include<stdio.h>
int main(void)
{
char s1[5];
printf("enter text:\n");
scanf("%s",s1);
printf("\n%s\n",s1);
return 0;
}
输入为:
1234567891234567
,我已经检查过它可以正常工作16个元素(我不明白,因为它超过5个元素)。12345678912345678
,它给了我一个错误segmentation fault: 11
(在这种情况下我给了17个元素)123456789123456789
,错误为Illegal instruction: 4
(在这种情况下我提供了18个元素)我不明白为什么会有不同的错误。这是C中scanf()
或字符数组的行为吗?我正在阅读的这本书对这些事情没有明确的解释。仅供参考我对指针一无所知。对此的任何进一步解释都会非常有用。
答案 0 :(得分:5)
这是在C?
中的scanf()或字符数组的行为
TL; DR - 不,你正面临undefined behavior的副作用。
在您的情况下,针对像
这样的代码进行详细说明 scanf("%s",s1);
你已经定义了
char s1[5];
输入超过4 char
的任何内容都会导致您的程序冒险进入无效的内存区域(超过分配的内存),而后者会调用undefined behavior。
一旦你点击UB,程序的行为就无法以任何方式预测或证明。它可以做任何可能的事情(甚至不可能)。
scanf()
中没有固有的东西阻止你阅读过长的输入并超出缓冲区,你应该通过使用字段宽度控制输入字符串扫描,如
scanf("%4s",s1); //1 saved for terminating null
答案 1 :(得分:2)
读取字符串时scanf
函数读取到下一个空白区域(例如换行符,空格,制表符等)或文件&#34;结束文件&#34;。它对你提供的缓冲区的大小有 no 的想法。
如果您读取的字符串比提供的缓冲区长,那么它将写出越界,您将有未定义的行为。
停止此操作的最简单方法是提供scanf
格式的字段长度,如
char s1[5];
scanf("%4s",s1);
请注意,我使用4
作为字段长度,因为字符串终结符也需要空间。
你也可以使用&#34; secure&#34; scanf_s
,您需要将缓冲区大小作为参数提供:
char s1[5];
scanf_s("%s", s1, sizeof(s1));