为什么我首先要在strcat()之前使用strcpy()?

为什么此代码会产生运行时问题:

char stuff[100]; strcat(stuff,"hi "); strcat(stuff,"there"); 

但这不是吗?

 char stuff[100]; strcpy(stuff,"hi "); strcat(stuff,"there"); 

strcat将查找null-terminator,将其解释为字符串的结尾,并在其中附加新文本,覆盖进程中的null-terminator,并在连接结束时写入新的null-terminator。

 char stuff[100]; // 'stuff' is uninitialized 

空终止符在哪里? stuff是未初始化的,所以它可能从NUL开始,或者它可能没有NUL在其中任何地方。

在C ++中,您可以这样做:

 char stuff[100] = {}; // 'stuff' is initialized to all zeroes 

现在你可以做strcat,因为’stuff’的第一个字符是null-terminator,所以它会附加到正确的位置。

在C中,你仍然需要初始化’stuff’,这可以通过以下两种方式完成:

 char stuff[100]; // not initialized stuff[0] = '\0'; // first character is now the null terminator, // so 'stuff' is effectively "" strcpy(stuff, "hi "); // this initializes 'stuff' if it's not already. 

在第一种情况下, stuff包含垃圾。 strcat要求目标和源都包含正确的以null结尾的字符串。

 strcat(stuff, "hi "); 

将搜索终止'\0'字符的内容,它将开始复制"hi " 。 如果它没有找到它,它将在数组的末尾运行,并且可能发生任意不好的事情(即,行为未定义)。

避免这个问题的一种方法是这样的:

 char stuff[100]; stuff[0] = '\0'; /* ensures stuff contains a valid string */ strcat(stuff, "hi "); strcat(stuff, "there"); 

或者你可以将stuff初始化为空字符串:

 char stuff[100] = ""; 

这将用零填充所有100字节的stuff (增加的清晰度可能值得任何小的性能问题)。

因为在调用strcpy之前, stuff是未初始化的。 声明后的stuff不是空字符串,它是未初始化的数据。

strcat将数据附加到字符串的末尾 – 也就是说它在字符串中找到空终止符并在此之后添加字符。 未初始化的字符串不具有空终止符,因此strcat可能会崩溃。

如果有初始化的stuff如下,你可以执行strcat:

 char stuff[100] = ""; strcat(stuff,"hi "); strcat(stuff,"there"); 

Strcat将字符串附加到现有字符串。 如果字符串数组为空,则不会找到字符串结尾( '\0' ),这将导致运行时错误。

根据Linux手册页,简单的strcat以这种方式实现:

  char* strncat(char *dest, const char *src, size_t n) { size_t dest_len = strlen(dest); size_t i; for (i = 0 ; i < n && src[i] != '\0' ; i++) dest[dest_len + i] = src[i]; dest[dest_len + i] = '\0'; return dest; } 

正如您在此实现中所看到的,除非将dest初始化为正确的c字符串值,否则strlen(dest)将不会返回正确的字符串长度。 你可能很幸运,在char stuff[100];有一个第一个值为零的数组char stuff[100]; ,但你不应该依赖它。

另外,我建议不要使用strcpystrcat因为它们可能导致一些意想不到的问题。

使用strncpystrncat ,因为它们有助于防止缓冲区溢出。