You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何第一种C语言字符串复制实现打印时出现未知符号?

为什么第一种字符串复制写法会出现未知符号?

这问题我之前写C的时候也踩过一模一样的坑!核心原因非常明确:第一种写法没有给复制后的字符串添加C语言字符串必需的终止符'\0'。

先搞懂C语言字符串的规则:C里的字符串本质是字符数组,但必须以'\0'(空字符)作为结束标记。printf("%s")这类函数会从指定地址开始逐个输出字符,直到遇到'\0'才会停止——如果找不到这个标记,它就会继续读取内存里的随机垃圾数据,直到碰巧遇到某个'\0',这就是你看到的“未知符号”的来源。

我们来拆解两种写法的差异:

第一种写法的问题点

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr) + 1), *p = str;
while (*constStr) {
    *p = *constStr;
    constStr++;
    p++;
}
printf("%s\n", str);
free(str);
  • 原字符串"Hello world"的末尾自带'\0',但你的循环条件是while (*constStr)——当*constStr等于'\0'时,这个条件不成立,循环直接终止了。
  • 你虽然用malloc(strlen(constStr)+1)申请了足够容纳'\0'的空间(strlen返回的是字符串长度,不包含末尾的'\0'),但这个空间里的'\0'根本没被复制进去,p指向的位置是malloc返回的未初始化内存,内容是随机的。
  • 所以printf输出时,会把复制的"Hello world"全部输出,然后继续读后面的随机垃圾数据,直到碰到某个'\0',就出现了乱码。

第二种写法为什么正常

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr) + 1);
for (int i = 0; i <= strlen(constStr); i++) {
    str[i] = constStr[i];
}
printf("%s\n", str);
free(str);
  • 这里的循环条件是i <= strlen(constStr):strlen(constStr)返回11("Hello world"的字符数),当i=11时,constStr[11]刚好是原字符串末尾的'\0',这一步把'\0'也复制到了str[11]的位置。
  • 这样str就成为了一个带正确终止符的合法C字符串,printf输出到'\0'就停止,自然能正常显示"Hello world"。

第一种写法的修复方案

只需要在循环结束后,手动给str加上终止符就行:

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr) + 1), *p = str;
while (*constStr) {
    *p = *constStr;
    constStr++;
    p++;
}
*p = '\0'; // 加上这一行,手动添加字符串终止符
printf("%s\n", str);
free(str);

内容的提问来源于stack exchange,提问作者Lion King

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:18:48