简体   繁体   English

C语言scanf复制多余的字符串

[英]C language scanf copies extra string

#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);
}

I typed "hello world" in the terminal, but the printf result is "helloworld world". 我在终端中输入了“ helloworld world”,但结果为“ helloworld world”。 Is there something wrong I'm doing? 我在做错什么吗?

When you declare 当你声明

char x[5];
char y[10];

In memory, you have something like: 在内存中,您将看到以下内容:

                     1 1 1 1 1 
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 
+---------+-------------------+
|. . . . .|. . . . . . . . . .| 
+---------+-------------------+
 ^         ^
 \-- x     \-- y

After the first scanf , you write hello\\0 in x 在第一个scanf ,在xhello\\0

                     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 . . . . . . . . .| 
+---------+-------------------+

After the second scanf , you write world\\0 in y 在第二个scanf ,您在yworld\\0

                     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 . . . .| 
+---------+-------------------+

When you type printf("%s", x); 当您键入printf("%s", x); you ask to type to write from x to the first \\0 , so "helloworld" is printed. 您要求键入从x到第一个\\0 ,因此将打印出"helloworld"

When you type printf("%s", y); 当您键入printf("%s", y); you ask to type to write from y to the first \\0 , so "world" is printed. 您要求键入从y到第一个\\0 ,因此将打印出"world"

Note: 注意:

The memory arrangement is not deterministic, you should have all kind of other results, even crashes... 内存排列方式不是确定性的,您应该获得所有其他结果,甚至崩溃...

You can find a good tutorial to use scanf here: http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html 您可以在此处找到使用scanf的好教程: http : //sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html

Never, never, really never use the "%s" format specifier without a WIDTH to tell scanf() how many characters it may put into the memory pointed to by the argument. 在没有WIDTH的情况下,绝对不要使用"%s"格式说明符来告诉scanf()它可以将多少个字符放入参数所指向的内存中,永远不要,永远不要。

char str[5];
scanf("%4s", str);

Strings in C are terminated by a null byte. C中的字符串以空字节终止。 So the string "hello" actually needs 6 bytes to store: 5 for the letters in "hello" and one for the null byte. 因此,字符串“ hello”实际上需要6个字节来存储:“ hello”中的字母5个,空字节1个。

The variable x is only 5 bytes wide, so it's not big enough to store the string "hello". 变量x只有5个字节宽,因此它不足以存储字符串“ hello”。 As a result, attempting to write this string to x writes past the end of the array. 结果,尝试将此字符串写入x超出数组末尾。 This invokes undefined behavior , which in this case manifests as writing to an adjacent variable. 这会调用未定义的行为 ,在这种情况下,这表现为写入相邻变量。

Increase the size of x to prevent overrunning the array. 增加x的大小以防止数组溢出。 You should also use a field width in the format specifier to specify the maximum number of characters to read: 您还应该在格式说明符中使用字段宽度来指定要读取的最大字符数:

char x[6];
char y[10];
scanf("%5s",x);
scanf("%9s",y);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM