1

/* 我观察到的是:

  1. 当我将“ab”之类的字符串提供给 b(array)
    时,输出为:“ab”“help”“dude”
  2. 当我给“abc”时
    ,输出是:“abc”“”“dude”
  3. 如果我给“abcd”,那么输出是:“abc”“d”“dude”

    很快 */

       #include<stdio.h>
       main()
       {
            char a[5]="help",b[3],c[10]="dude";
         scanf("%s",b);
         printf("\t%s",b); 
         printf("\t%s",a);
         printf("\t%s",c);
       }
    
       /* what i dont get is :
        Here iam  gaving a string to b(array),  why, if the string has more than the  
        required no. of charecters, its printing those charecters in other arrays 
       (though i had not assiged scanf to other arrays )?   
    
4

7 回答 7

5

Remember that a string in C needs space for a null terminator. If there is no space, printing will continue "to the next nul". Here is how your memory looks at initialization:

h  e  l  p \0 \0 \0 \0  d  u  d  e \0
^             ^         ^
a             b         c

When you read in a string ab in the location pointed to by b:

h  e  l  p \0  a  b \0  d  u  d  e \0
^              ^        ^
a              b        c

And all is well. But abc gives:

h  e  l  p \0  a  b  c \0  u  d  e \0
^              ^        ^
a              b        c

and when you print b you will get abc; printing c will get you nothing (first character is '\0').

Finally, with an input of abcd you get

h  e  l  p \0  a  b  c  d \0  d  e \0
^              ^        ^
a              b        c

And printing c will result in "d" - exactly as you are seeing.

In fact, the order in which things are stored in memory is not "defined", although usually the compiler will do something similar to the above. So while you know that you can't write to memory that isn't yours, you can't be sure what will happen when you do (as in your case). That is why it is called "undefined behavior". You can't rely on other compilers giving you the same result - or even the same compiler giving you the same result...

Make sense?

The solution, of course, is to allocate more space to b. That would result in more '\0' between b and c, and nothing gets overwritten.

edit - I did just realize that it seems that the order in which b and a are stored is backwards from how I just described it - because it's a, not c that is getting overwritten. Which shows that the compiler orders things as it jolly well pleases, and that I ought to wear my glasses when I write detailed answers. But the principle is exactly the same - so I will "leave the rest as an exercise for the student".

于 2013-10-19T05:47:16.020 回答
1

您的数组按以下顺序放置在内存中

c[10]、b[3]、a[5]

因此,如果数组 b 包含的字符多于它可以容纳的字符,那么它的一些字符将与数组 a 重叠,考虑这两个数组 b 和 a,因为它们在内存中

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]

当你在 b 中输入“abc”时,你得到了

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]
'a'  'b'  'c'  '\0' 'e'  'l'  'p'  '\0'

所以在执行语句之后

 printf("\t%s",b); 
 printf("\t%s",a);

输出是

"abc" ""

因为 a[0] 包含 '\0'

当您输入“abcd”时,您得到了

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]
'a'  'b'  'c'  'd' '\0'  'l'  'p'  '\0'

输出是

"abcd" "d"

因为 a[0] 包含 'd' 而 a[1] 包含 '\0'

于 2013-10-19T06:02:37.010 回答
0

So what's really happening is you are going outside the end of your arrays and overwriting memory.

When you provide 'ab' as input to b, it works because b is large enough to store 'ab' and the \0 as others have mentioned.

When you provided 'abc' as input, b does not have enough space allocated to store abc and the null so it only stores 'abc' and then the null appears to get written to the first byte of the a array, which means it's just an empty string... or maybe it doesn't, this is the undefined part. Who knows what is stored outside your array. It just so happens you are probably getting lucky since those arrays you have defined are most likely in contiguous memory.

When you provide 'abcd' as input, the d and the null get written to the a array.

Many times in less-simple programs, you'll get a SEGV with programming errors like this.

于 2013-10-19T05:54:51.943 回答
0

b[3]是 3 个字符的数组。但是字符串abc由 4 个字符组成,最后一个是\0,表示字符串的结尾。因此,如果您希望能够存储abc,则需要声明至少 4 个字符的数组,而不是 3

于 2013-10-19T05:42:26.970 回答
0

当您提供abc输入时,您的数组b会被填满(因为它只有 3 个位置)并且没有\0字符空间。结果,当您尝试将其打印为字符串时..它会溢出并导致错误

对于要打印的字符串,它必须具有以下格式: stringtext\0但是当您用完数组中的所有空格时,您在打印时b没有留下任何空间\0,因此会出现错误

此语句在您的代码中也是错误的:

scanf("%s",&b);

它应该是 :

scanf("%s",b);
于 2013-10-19T05:43:11.210 回答
0

当您将“abc”放入b[3]时,它会超过数组的末尾。该abc字符串是四个字节,因为它的末尾有一个 nul 终止符。

由于它是未定义的行为,因此从技术上讲,任何事情都可能发生,但实际发生的是字符串末尾的 nul 正在覆盖内存中下一个变量的第一个字符,使其变为空字符串。

最快的解决方案是确保您的字符数组足够大以存储所有字符和终止符:

char b[4] = "abc";

或者让编译器为这个特殊的简单情况处理它:

char b[] = "abc";
于 2013-10-19T05:44:22.347 回答
0

这只是未定义行为的一种情况。b[3]可以存储三个字符的字符串(包括\0),但是当您的输入是abc四个字符的字符串时,您不能将其存储在数组中b。你会得到任何东西。

于 2013-10-19T05:56:19.063 回答