我有两种方法可以达到同样的目的,第一种方式打印未知符号,第二种方式打印出我想要的。
第一种方式:
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);
结果:
第二种方式:
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);
结果:
为什么第一种结果看起来很奇怪?
答案 0 :(得分:1)
不,你没有null终止字符串。这是使用printf
格式说明符将指针传递到%s
中的非空终止char数组的未定义行为。
在循环之外制作*p=0
。这将使null终止char数组。
第二种方式是打印,因为您复制了\0
数组的strlen(constStr)
索引中的<=
。注意循环条件中的printf
。
那些奇怪的信件来自哪里?
根据%s
进行思考。当它看到\0
格式说明符时,它从作为参数提供给它的地址开始打印。现在什么时候停止?当它找到const char *constStr = "Hello world";
char *str = malloc(strlen(constStr) + 1), *p = str;
while (*p++ = *constStr++); // here `\0` will be copied.
printf("%s\n", str);
free(str);
时。在这里它没有找到它,它读出你分配的内存。那些内存上的那些位模式被证明是那些不可打印的字符。这就是你所看到的。正确的方法是:
\0
使用琴弦时,请务必保持角落箱的清洁。我的意思是,检查{{1}}是否被复制等。当我们实现字符串例程时,这是一个很常见的问题。
答案 1 :(得分:1)
要修复第一个,请在字符串的末尾添加一个null:
const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr) + 1), *p = str;
while (*constStr) {
*p = *constStr;
constStr++;
p++;
}
*p = '\0'; /* <-- HERE */
printf("%s\n", str);
free(str);
注意:您正在修改指向临时的指针 - 不推荐。使用与str
相同的方法,使用另一个移位的指针。