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

时间:2013-09-16 23:20:42

标签: c cstring

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

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

但这不是吗?

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

5 个答案:

答案 0 :(得分:34)

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

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

null终止符在哪里? 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.

答案 1 :(得分:5)

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

strcat(stuff, "hi ");

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

避免此问题的一种方法是:

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

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

char stuff[100] = "";

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

答案 2 :(得分:0)

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

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

如果要初始化stuff如下所示,你可以执行strcat:

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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;
   }

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