C语言利用字符串数组读取字符串的误区

最近碰到一个很奇怪的问题,想想关了电脑也要再开机记录下来

主要代码如下:

int main()
{
    char* key[2];
    
    scanf("%s", &key[0]);
    scanf("%s", &key[1]);

    printf("%s   \n", &key[0]);
    return 0;
}

要从控制台中读取输入的字符串,定义了一个char*类型的数组,结果出问题了。

当输入:  whos     who 输出:whoswho

当输入: wwwwww   dddddd 输出:wwwwdddddd


有多纠结我就不说了,和同学讨论了好久得出结论(可能有误)

char* 在C语言中占四个字节,因为定义的key是个数组,在声明时为它分配一块连续的内存,于是数组key的每个单元都被固定成四个字节

对于第一种情况,whos正好占了四个字节,最后的终结符(记得是\0)越界放到了key[1]里,随后被写入key[1]内存地址的数据覆盖掉了,于是系统不知道key[0]到什么地方结束,一直往后读,直到遇到了key[1]的终结符,所以把key[1]一块输出了。

对于第二种情况也类似,6个w放到4个字节里放不下,只能存放前四个,后面两个越界放到了key[1]里,随后被写入key[1]内存地址的数据覆盖掉了。虽然后面的6个d也超出了范围,但是这个数组只有两个长度的大小,key[i]只是记录了首地址,并没有记录结束位置的地址,于是这6个d把为这个数组分配的8个字节内存的后面一部分内存给占用了,所以最后一个字符串完整的输出了。


假设还是定义key的长度为2,但是只读取了一个字符串,不管它长度多大,都能完整输出,因为它越界的部分没有被覆盖掉。

因此,对于这种输入的字符串大于4个字节的情况,只有输入的最后一个字符串能完整的输出。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值