c语言的字符串数组初始化问题

我的程序是这样的。intmain(intargc,char**argv){charstr1[5],str2[4];scanf("%s%s",str1,str2);prin... 我的程序是这样的。
int main(int argc, char **argv)
{
char str1[5],str2[4];
scanf("%s%s",str1,str2);
printf("%s\n",str1);
printf("%s\n",str2);
return 0;
},如果str1对应的输入字符串是5个的话就会出错,比如我输入abcde回车abcd回车,打印出来的是abcdeabcd,abcd.。如果我第一个字符串输入的字符个数少于5个的话就不会有问题,请问这是为什么?
展开
 我来答
cdyzxy
2014-02-13 · TA获得超过2.1万个赞
知道大有可为答主
回答量:1.4万
采纳率:85%
帮助的人:3756万
展开全部
  1. 你申请数组空间后,内存中存放字符的顺序是:

    str1[0],str1[1],str1[2],str1[3],str1[4],str2[0],str2[1],str2[2],str2[3]

  2. 当输入字符串是:abc 123时,存储的数据str1[0]~str1[4],str2[0]~str2[3]为:

    ‘a','b','c',0,xx,'1','2','3',0

    其中,xx表示一个不关心的任意值,也就是说输入字符串"abc"需要占用4个字节的存储空间

  3. 当输入字符串1为"abcde"时,存储的数据为:'a','b','c','d','e',0,xx,xx,xx

    字符串末尾的0已经超出了str1开设的存储空间而存放到了str2[0]位置

    接着再输入字符串"1234"时,str2[0]的str1字串的结尾符被字符'1'覆盖,

    存储的数据为:'a','b','c','d','e',’1‘,’2‘,’3‘,’4‘,0

    而且由于str2输入字符数为4个其占用空间也超出了str2的空间范围,那么上边存储的0值也不知道覆盖了什么变量的位置,导致其他变量的值被冲掉了。

  4. 当执行printf("%s\n",str1);时,printf从str1[0]开始输出的字符串(遇0结束输出)为abcde1234

  5. 当执行printf("%s\n",str2);时,printf从str2[0]开始输出的字符串(遇0结束输出)为1234

所以你输入的第1个字符串字符数少于5时,存储不会溢出,多于4个时,末尾的0就会被输入的str2所覆盖而失效,且多于5的字符也会被覆盖。scanf并不能保证输入字符的长短不会溢出,你应当在设计程序时考虑到这点,预先定义足够的字符串保存空间或用其他方法来避免这个问题的出现。

追问
为什么str1过界的字符就一定要到str2里面呢,我看了这2个数组的地址,是连在一起的,是不是栈在分配数据的时候就默认字符数组分一起,然后整数数组分一起?
追答
可以说由于你开设两个空间的定义语句的编译结果导致的,编译程序自动把你这两个空间紧接着开辟了,这是与你的变量定义语句以及编译程序相关的。但你在程序中不能假设这个是一定的,只能说碰巧了。
cpucash
推荐于2017-12-16 · TA获得超过1584个赞
知道小有建树答主
回答量:1457
采纳率:66%
帮助的人:971万
展开全部
字符串至少要有一个结束符
%s的打印,是以结束符为标志的

两点要理解
1、字符串和字符数组是不一样的两个东西
虽然都是这么定义,但是字符串需要\0这个结束符,字符数组不需要
2、变量的内存模型
程序运行时,要申请内存来保存变量的数据,并且是紧挨着的,具体顺序我忘记了,有的编译器可能不同
按你的程序,str1在前,str2在后,并且是紧挨着的,str1 5个内存空间,紧挨着str2 4个空间,后面可能还要空间没有使用
你输入abcde后,占用6个空间,吧str2的一个空间占用了,这里是不检查越界的
接着输入abcd,把str1的结束符覆盖掉,并且也是越界,因为str2是4个字符空间,结束符要占一个,是5个空间,把内存中str2后面的一个内存写入结束符,如果后面还有变量的话,程序会出错
这样打印%s时,str1检查结束符是str2后面的结束符,所以是abcdeagcd,str2是abcd
追问
那是不是说每种类型的数据在栈中分配的时候都是分在连续的地址中的?
追答
应该是这样的,不过也要看编辑器,还有对齐方式等因素
其实像这种问题,一般来说没必要搞的太清晰,知道个大概即可
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
伏昕保访冬
2019-06-09 · TA获得超过3557个赞
知道大有可为答主
回答量:3117
采纳率:32%
帮助的人:225万
展开全部
char
*a[
]={"asdf","asdfsadf"}这个是指针数组,相当于char
*a[2]={"asdf","asdfsadf"}
然后第一个是char
a[1]
=
{'a','s','d'},char
a[2]
=......
char
a[
]={"asdf","asdfsadf"}
这样是不行的,如果是字符数组,就得用单引号,双引号是字符串,
char
m1[
]={'a','b','c''\0'}
这个是字符数组,
char
m1[
]={'a','sdfb','c''\0'},这样是不行的,单引号里面是一个字符,双引号才能出现连续字符。
如有不明可以追问。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
小七q幸福
2014-02-12 · 超过17用户采纳过TA的回答
知道答主
回答量:40
采纳率:0%
帮助的人:26.6万
展开全部
= =骚年你上课要认真啊~字符串在内存中要多占用一个字节,以\0结尾,所以你输五个第五个就不会显示啦~应该把那个字符数组定义的大一点,就好啦~
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zaobao000
2014-02-12 · TA获得超过348个赞
知道小有建树答主
回答量:319
采纳率:100%
帮助的人:232万
展开全部
字符串\0结尾,所以少一位
str1和str2在内存中连着,所以打印的时候abcde之后没有\0会接着把后面打出来
那为什么str2输出正确呢?
其实在输入的时候,str1的\0是也是被输入的,但它之后被str2得a覆盖了,而str2的\0没有被覆盖,所以读到str2的d就停止了。
但str2的a在它本来该在的位置,是正确地,而str2的\0才是不合法的,这个\0会把程序其他地方覆盖掉,这是很危险的哦。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(5)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式