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

我是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(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)
行为如下:

  • 跳到dest中的第一个
    '\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);