C “你怎么看?”;腾出地方来”;为了一根绳子?

C “你怎么看?”;腾出地方来”;为了一根绳子?,c,c-strings,C,C Strings,我将这段代码发布到其他地方,以了解它为什么没有按预期输出“ratdog”。有人说没有足够的空间在“老鼠”后面加上“狗”之类的词。他们是什么意思 #include <stdio.h> char *strcat(char*, char*); char* strcat(char *s, char *t) { char* result = *s; while(*s != '\0') printf("%s", *s); *s++; //

我将这段代码发布到其他地方,以了解它为什么没有按预期输出“ratdog”。有人说没有足够的空间在“老鼠”后面加上“狗”之类的词。他们是什么意思

#include <stdio.h>

char *strcat(char*, char*);

char* strcat(char *s, char *t) {
    char* result = *s;
    while(*s != '\0')
        printf("%s", *s);
        *s++;   // advance pointer until you reach the null terminator.

    while(*t != '\0')
        *s = *t;    // copy t to the end of s until we reach the end of t.
    return (char*) result;
}

int main() {
    char rat[] = "rat";
    char dog[] = "dog";
    printf("%s", strcat(rat, dog));
    return 0;
}
#包括
字符*strcat(字符*,字符*);
char*strcat(char*s,char*t){
char*result=*s;
而(*s!='\0')
printf(“%s”,*s);
*s++;//前进指针,直到到达空终止符。
而(*t!='\0')
*s=*t;//将t复制到s的末尾,直到到达t的末尾。
返回(char*)结果;
}
int main(){
字符rat[]=“rat”;
char dog[]=“dog”;
printf(“%s”,strcat(鼠、狗));
返回0;
}

您的代码有3个问题:

  • 复制时增加t和s,否则这是一个无限循环

    while(*t != '\0')
      *s = *t; //See you're only assigning
    
    while(*t != '\0')
      *(s++) = *(t++); //increment them
    
  • 类似地,@ihonen:
    *s++;//前进指针,直到到达空终止符。
    不在循环体中

  • 为指向的数据源指针分配更多内存,以便它可以包含连接的字符串和
    \0

      char rat[7] = "rat"; //See i am allocating len(rat) + len(dog) + '\0' = 3+3+1 = 7 
      char dog[] = "dog";
      printf("%s", strcat(rat, dog));
    
  • 第三,您希望在第二个循环之后附加
    \0
    *s
    ,就像这样
    *s='\0'


  • 如果您的代码正在执行此操作:

        char rat[] = "rat";
        char dog[] = "dog";
    
    在这些行中,编译器将分配
    char
    类型的空间来保存这3个字符,再加上一个额外的空终止符(总共4个字节)

    如果然后尝试附加到这些字符串中的一个,它将不起作用,因为您是静态声明它们的,并且内存中的空间是在那时分配的。在C中创建变量后,可用空间量是固定的,除非以后明确更改它。因此,正如您所说的:变量
    rat
    指向一个内存位置,该位置被分配用来容纳3个字符和空终止符,因此没有空间在末尾添加“dog”

    如果您需要“ratdog”,那么您需要创建一个足够大的新变量来容纳它

    你可以这样做:

    #include <stdio.h>
    #include <string.h>
    int main(void) {
        char rat[] = "rat";
        char dog[] = "dog";
        char ratdog[7];
    
        strncpy(ratdog, rat, 3);
        strncpy(&ratdog[3], dog, 4);
        printf("%s", ratdog);
        return 0;
    }
    
    #包括
    #包括
    内部主(空){
    字符rat[]=“rat”;
    char dog[]=“dog”;
    charratdog[7];
    strncpy(大鼠,3只);
    strncpy和ratdog[3],dog,4);
    printf(“%s”,ratdog);
    返回0;
    }
    
    请注意,第二个strncpy正在复制四个字节。第4个字节是
    狗的空终止符


    假设,如果使用一个
    malloc
    函数创建了
    rat
    ,您也可以尝试使用
    realloc
    扩展其大小,但在这种情况下,这不起作用。

    您发布的代码不会编译。代码还有一个无限循环(第一个循环从顶部开始计数)。行
    *s++不在循环中-这就是为什么您应该始终使用花括号(至少在您熟悉C/C++并确切知道您在做什么之前)?另外,您不必硬编码
    strncpy()
    的最后一个参数,您可以编写:
    strncpy(ratdog,rat,strlen(rat))
    strncpy(ratdog+3,dog,sizeof(dog))当然,你也可以这样做。我硬编码了
    strncpy
    size参数,以清楚地说明需要从
    dog
    获取
    \0
    。这是一个人为的例子,我不打算将其发布到生产中:)不使用
    char-rat[7]=“rat”的原因实际上只是因为这就是最初问题的框架。按照你的建议去做肯定会让事情变得更容易,但可能会错过原来问题的意图。为什么?这就是C如何知道字符串何时正确完成的?是的,它充当一个保留字符,用于表示字符串的结尾,通常称为以null结尾的字符串()