31

Why does this code produce runtime issues:

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

but this doesn't?

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

5 回答 5

45

strcat将查找空终止符,将其解释为字符串的结尾,并将新文本附加到那里,在此过程中覆盖空终止符,并在连接末尾写入一个新的空终止符。

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

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

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

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

现在你可以做 strcat,因为 'stuff' 的第一个字符是空终止符,所以它会附加到正确的位置。

在 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.
于 2013-09-16T23:24:13.320 回答
5

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

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] = "";

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

于 2013-09-16T23:25:08.750 回答
2

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

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

如果要按stuff以下方式进行初始化,则可以执行 strcat 的:

char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");
于 2013-09-16T23:25:23.740 回答
0

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

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

于 2013-09-16T23:32:49.663 回答
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;
   }

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

于 2013-09-16T23:34:01.393 回答