C 字符的零终止*
我是Ubuntu下C编程和开发的新手 我有一些示例代码:C 字符的零终止*,c,ubuntu,strcat,C,Ubuntu,Strcat,我是Ubuntu下C编程和开发的新手 我有一些示例代码: char * output1 ="one\0two\0"; char * output2 = ""; char * first = "one"; char * second = "two"; char * term = "\0"; output2 = malloc(20); strcat(output2,first); strcat(output2,term); strcat(output2,second); strcat(o
char * output1 ="one\0two\0";
char * output2 = "";
char * first = "one";
char * second = "two";
char * term = "\0";
output2 = malloc(20);
strcat(output2,first);
strcat(output2,term);
strcat(output2,second);
strcat(output2,term);
printf("%s\n",output2);
printf("%s\n",output1);
输出如下:
onetwo
one
output1
的输出停止,因为其中有一个\0
。但是为什么在我添加了\0
之后,输出2
没有停止打印
我做错了什么?如何将\0
添加到输出2
以使其输出打印
one
提前感谢。对于C字符串,
\0
字符总是标记字符串的结尾。因此,字符串“
和字符串“\0”
实际上意味着相同的东西,即使后者中有一个额外的字节
也就是说,strcat(foo,“\0”)
不会将任何内容附加到foo
字符串“\0”
相当于一个char[]{0,0}
。当您使用strcat时,它会覆盖当前的空终止符,将值复制到第一个'\0'
,因此会发生以下情况:
// ... are garbage values
strcat(output2,first); // output2 is { 'o', 'n', 'e', '\0', ... }
strcat(output2,term); // '\0' is overwritten with `\0` so no change.
strcat(output2,second); // output2 is { 'o', 'n', 'e', 't', 'w', 'o', '\0', ... }
strcat(output2,term); // '\0' is overwritten with `\0` so no change.
要将此输出设置为一个:
output2[3] = 0;
// or this maybe easier to read
output2[3] = '\0';
正如评论(和其他答案)中指出的:
是未定义的行为,因为strcat试图查找第一个空字符。因此,只需将第一个字符设置为\0
:
output2 = malloc(20);
output2[0] = 0; // or '\0'
strcat(output2,first);
代码
output2 = malloc(20);
strcat(output2,first);
分配20个随机字节,然后首先向其中添加字符串变量
但是output2指向20个字节,可以包含任何内容,因此其中可能有“A\0B\0”,然后strcat会找到一个\0并首先添加到该字节中
您需要初始化输出2
memset(output2,0,20);
strcat(dest,src)
行为如下:
'\0'
src
复制到dest
中,覆盖以前的空字符并在末尾添加一个空字符strcat(output2,term)
调用被strcat(outpu2,second)
调用覆盖
请注意,您有一个未定义行为(UB)的案例:
现在,当您编写output2=malloc(20)
时,无法保证分配的内存已初始化为空strcat()
将搜索一个'\0'
,它可能在分配的20字节malloc()
之后很远
你要么
output2 = calloc(20, sizeof(char));
strcat(output2,first);
strcat(output2,term);
strcat(output2,second);
strcat(output2,term);
或
或
@HACKS没有看到任何UB,请指出。注:
output2=malloc(20)代码>我现在看到了<代码>输出2=malloc(20);strcat(输出2,第一)
是UB,因为输出2
没有被确定的'\0'
终止,后面跟着strcat(输出2,第一)
期望输出2
终止。strcat
具有简单的定义良好的行为,在手册页上有详细描述。仔细阅读,然后将其应用到代码中,应该会立即告诉您这里发生了什么。感谢您的小解释,但当我尝试此操作时:strcat(output2,first);输出2[3]=0;strcat(输出2,秒)代码>我仍然得到一个两个输出,这是一个好答案的开始,但是请注意输出2=malloc(20)的UB;strcat(输出2,第一)
@Leviathan:与之前一样,当您使用strcat时,它将覆盖找到的第一个空字符。这必须在之后完成。为什么要设置所有20个,只做第一个字符。技术上你是对的,当然,这只是我的一个习惯,因为我发现调试时更容易看到垃圾何时进入数组。
output2 = calloc(20, sizeof(char));
strcat(output2,first);
strcat(output2,term);
strcat(output2,second);
strcat(output2,term);
output2 = malloc(20);
strcpy(output2,first);
strcat(output2,term);
strcat(output2,second);
strcat(output2,term);
output2 = malloc(20);
memset(output2, '\0', 20); // Or output2[0] = '\0';
strcat(output2,first);
strcat(output2,term);
strcat(output2,second);
strcat(output2,term);