C语言字符串问题

一图和二图 3图和4图 进行对比。在3图和4图中,只要指定长度大于4就能得到正确的结果。 我想知道:1. 字符串初始化,如果逐个赋值的话,系统不是会自动添加'\0'吗,那为何 手动添加才得到我预期的结果呢?(1图和2图) 2. 是否因为系统自动添加结束符导致3图和4图的情况?(即:如果指定长度小于4+1 则字符串的储存会出现问题) 求高手解答

1. 字符串初始化,如果逐个赋值的话,系统不一定会自动添加'\0',除非指定了长度且指定的长度大于等于你赋值的字符的个数加1,即最小为你赋值的字符个数加1。假设你指定的字符个数为n,长度为len,则系统会将剩下的(len-n)个元素都赋值为'\0',当n等于len时,不会添加任何'\0'。
之所以出现图1的情况,是因为当前栈顶刚好等于(纯粹是碰巧)'\0',假设当前栈顶为100,则有[100]='\0';,而为m_str分配内存时,栈顶要减4,因为栈设计成了先自减(即分配内存)后入栈,于是[100]='\0';[99]='P';[98]='O';[97]='T';[96]='S';m_str赋值为地址96,当前栈顶为96。当为u_str分配内存时,栈顶又要减4,于是[100]='\0';[99]='P';[98]='O';[97]='T';[96]='S';[95]='P';[94]='O';[93]='T';[92]='S';u_str赋值为地址92,当前栈顶为92。当计算m_str的长度时会从最低96开始,一直计算到99(遇到第一个'\0'前停止),所以m_str的长度为4,同理,计算u_str的长度时会从92开始,一直计算到99,所以其长度为8,从以上分析中显然可以看出,这两个字符串是不相等的,所以strcmp返回-1。
图2就不用过多解释了,手动添加了'\0',输出自然是那样的。又由上面对于图1的解释,要分析出出现图3和图4的原因,也是很容易的了,这里也不解释了。追问

大佬☕️

温馨提示:答案为网友推荐,仅供参考
第1个回答  2019-06-10

字符串初始化,如果逐个赋值的话,系统不是会自动添加'\0'吗

不是。

图一就是长度为4的数组,图二长度为5

图三会是添加\0,但是是会把后面所有的都设为\0

因为图一和图四不以\0结尾,所以不能用strlen和strcmp,会越界

图四也可以用char str[4] = "stop"这样赋值。如果不手动加长度就会是5了。

第2个回答  2019-06-10
我也试了一下,没问题,你到底是什么问题,是要在s1或s2中输入空格吗?那么用gets函数;
gets()函数用来从标准输入设备(键盘)读取字符串直到换行符结束,但换行符会被丢弃,然后在末尾添加'\0'字符。
其调用格式为:gets(s);
其中s为字符串变量(字符串数组名或字符串指针)。
gets(s)函数与scanf("%s:",&s)/* scanf("%s",s) */相似,但不完全相同,使用scanf("%s",&s);函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。
你改为:
#include<stdio.h>
void main()
{ char s1[50],s2[50];
gets(s1);
gets(s2);
printf("%s\n",s1);
printf("%s\n",s2);
}
这样就用回车表示输入结束追问

我只是想知道为何会出现我发的图片的结果

第3个回答  2019-10-03
char *p1="abcd", *p2="ABCD", str[50]="xyz";
strcpy(str+2,strcat(p1+2,p2+1));//将p2+1连接到p1+2后面,再拷贝到str+2里面
printf("%s",str);//p1+2
为cd
//p2+1
为BCD
strcat(p1+2,p2+1)

cdBCD
str+2
为z
strcpy(str+2,strcat(p1+2,p2+1))//
为xycdBCD
此处z被覆盖了
第4个回答  2019-06-11
p1
p2
str
记录的都是字符串的首地址
strcat拼接字符串,
p1位置是‘a’,+2,后移2个
到'c'
得到cd
p2位置是‘A’,+1,后移1个
到'B'
得到BCD
拼接为
cdBCD
strcpy复制字符串
str位置是'x'
+2
后移2个
到‘z’位置
从‘z’位置开始复制,cdBCD就替换了“xyz”
从z以后的所有
所有就得
xycdBCD
相似回答