C语言 scanf时与char数组混淆

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7277546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:34:07  来源:igfitidea点击:

Confused with the char array when scanf

cmemorycharscanf

提问by user918304

I am confused with one tiny program.

我对一个小程序感到困惑。

#include <stdio.h>

#define LEN 10

int main()
{
    char str1[LEN] = "##代码##";
    char str2[LEN] = "##代码##";

    scanf("%s", str1);
    scanf("%s", str2);

    printf("%s\n", str1);
    printf("%s\n", str2);

    return 0;
}

If my input are:

如果我的输入是:

mangobatao
mangobatao123456

mangobatao
mangobatao123456

Why should the output be:

为什么输出应该是:

123456
mangobatao123456

123456
mangobatao123456

And not:

并不是:

mangobatao
mangobatao123456

mangobatao
mangobatao123456

How has the chararray has been allocated in the memory?

char数组是如何在内存中分配的?

回答by Carl Norum

Well, a 10 character chararray won't fit "mangobatao", since it has 10 characters - there's no room for the null terminator. That means you've caused undefined behaviour, so anything could happen.

嗯,一个 10 个字符的char数组不适合"mangobatao",因为它有 10 个字符 - 空终止符没有空间。这意味着您造成了未定义的行为,因此任何事情都可能发生。

In this case, it looks like your compiler has laid out str2before str1in memory, so when you call scanfto fill str2, the longer string overwrites the beginning of str1. That's why you see the end of what you think should be in str2when trying to print str1. Your example will work fine if you use a length of 100.

在这种情况下,看起来您的编译器str2之前已经str1在内存中进行了布局,因此当您调用scanffill 时str2,较长的字符串会覆盖str1. 这就是为什么您在str2尝试打印时会看到您认为应该结束的内容str1。如果您使用 100 的长度,您的示例将正常工作。

回答by Aman Singh

I think your compiler has allocated space for str2[10] just 10 characters before the str1 pointer.

我认为您的编译器在 str1 指针前仅 10 个字符为 str2[10] 分配了空间。

Now, when you scanf a string of length 16 at str2, the string terminator '\0' is appended at str2 + 17th position, which is infact str1 + 7.

现在,当您在 str2 处扫描长度为 16 的字符串时,字符串终止符 '\0' 附加在 str2 + 17th 位置,实际上是 str1 + 7。

Now when you call printf at str1, the characters read are actually str2 + 11, str2 + 12,..., str2 + 16 until the null terminator is encountered at str2 + 17 (or str1 + 7). The printf at str2 must be obvious.

现在,当您在 str1 处调用 printf 时,读取的字符实际上是 str2 + 11、str2 + 12、...、str2 + 16,直到在 str2 + 17(或 str1 + 7)处遇到空终止符。str2 处的 printf 必须是显而易见的。