C语言scanf复制额外的字符串 #包括 #包括 int main() { charx[5]; chary[10]; scanf(“%s”,x); scanf(“%s”,y); printf(“%s%s”,x,y); }
我在终端中输入了“hello world”,但printf结果是“helloworld world”。C语言scanf复制额外的字符串 #包括 #包括 int main() { charx[5]; chary[10]; scanf(“%s”,x); scanf(“%s”,y); printf(“%s%s”,x,y); },c,C,我在终端中输入了“hello world”,但printf结果是“helloworld world”。 我做错什么了吗?永远,永远,真的永远不要使用“%s”格式说明符(没有宽度)来告诉scanf()它可以将多少字符放入参数指向的内存中 #include <stdio.h> #include <string.h> int main() { char x[5]; char y[10]; scanf("%s",x); scanf("%s",y);
我做错什么了吗?永远,永远,真的永远不要使用
“%s”
格式说明符(没有宽度)来告诉scanf()
它可以将多少字符放入参数指向的内存中
#include <stdio.h>
#include <string.h>
int main()
{
char x[5];
char y[10];
scanf("%s",x);
scanf("%s",y);
printf("%s %s",x,y);
}
C中的字符串以空字节结尾。所以字符串“hello”实际上需要存储6个字节:5个用于“hello”中的字母,1个用于空字节 变量
x
只有5个字节宽,因此它不够大,无法存储字符串“hello”。因此,尝试将此字符串写入x
时会写入超过数组末尾的内容。这将调用,在本例中表现为写入相邻变量
增加x
的大小以防止阵列溢出。还应在格式说明符中使用字段宽度来指定要读取的最大字符数:
char str[5];
scanf("%4s", str);
当你申报时
char x[6];
char y[10];
scanf("%5s",x);
scanf("%9s",y);
在内存中,您有如下内容:
char x[5];
char y[10];
在第一次scanf
之后,您将hello\0
写入x
1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
+---------+-------------------+
|. . . . .|. . . . . . . . . .|
+---------+-------------------+
^ ^
\-- x \-- y
在第二次scanf
之后,在y
1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
+---------+-------------------+
|h e l l o|0 . . . . . . . . .|
+---------+-------------------+
当您键入printf(“%s”,x)时您要求键入以从x
写入
第一个\0
,因此打印“helloworld”
当您键入printf(“%s”,y)时
您要求键入以从y
写入
第一个\0
,因此打印“世界”
注:
内存安排是不确定的,你应该有各种其他的结果,甚至崩溃
你可以在这里找到一个很好的使用scanf的教程:我仍然很好奇为什么它不在第二个“l”之后终止,比如打印“hell”(是的,这不是故意的),因为它是未定义的行为。这里没有什么有意义的“为什么”。任何事情都有可能发生。我看不出它为什么会在“第二个l之后”终止。对字符串使用scanf,即使使用宽度说明符,也有多频繁的意义?@supercat每年2到3次。在输入行可能包含或可能不包含空格字符的情况下,如何确保明智的行为?@supercat不使用
scanf()
在这种情况下。@supercat我不确定我是否在跟踪你。
1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
+---------+-------------------+
|h e l l o|w o r l d 0 . . . .|
+---------+-------------------+