如何编写适用于两个动态数组的 strcat 函数

How to code a strcat function that works with two dynamic arrays

正如我们所知,strcat 函数将一个 C 字符串连接到另一个 C 字符串上,形成一个包含另外两个 C 字符串的大 C 字符串。

我的问题是如何创建一个 strcat 函数来处理两个动态分配的数组。

所需的 strcat 函数应该能够适用于任何大小的 myStr1 和 myStr2

//dynamic c-string array 1
char* myStr1 = new char [26];
strcpy(myStr1, "The dog on the farm goes ");

//dynamic c-string array 2
char* myStr2 = new char [6];
strcpy(myStr2, "bark.");

//desired function
strcat(myStr1,myStr2);
cout<<myStr1; //would output 'The dog on the farm goes bark.'

这是我自己能做到的:

//*& indicates that the dynamic c-string str1 is passed by reference
void strcat(char*& str1, char* str2) 
{
    int size1 = strlen(str1);
    int size2 = strlen(str2);
    //unknown code
    //str1 = new char [size1+size2]; //Would wipe out str1's original contents
}

谢谢!

您分配内存并使您的指针指向该内存。然后你 覆盖 指针,使它们指向其他地方。例如的分配myStr1 导致变量指向字符串文字而不是您分配的内存。您需要将字符串复制到您分配的内存中。

当然,这种复制会导致另一个问题,因为您似乎忘记了 C 字符串需要一个额外的字符作为终止符。因此,具有 5 个字符的 C 字符串需要 space 六个 个字符。


至于你的串联功能,你也需要在这里做复制。为两个字符串 加上 分配足够的 space 一个终止符。然后将第一个字符串复制到新内存的开头,将第二个字符串复制到末尾。

您还需要一个临时指针变量来分配您分配的内存,否则 "would wipe out str1's original contents"(不完全正确,您只是让 str1 指向其他地方,丢失了原始指针)。

您首先需要更好地理解指针的工作原理。例如您的代码:

char* myStr1 = new char [25];
myStr1 = "The dog on the farm goes ";

首先分配 25 个字符,然后忽略指向该分配区域的指针(技术术语是 "leaks it")并设置 myStr1 指向字符串文字。

该代码应该使用 strcpy 而不是从字符串文字复制到分配的区域。除了该字符串是 25 个字符之外,因此您需要为至少 26 个字符分配 space,因为 ASCII NUL 终止符 (0x00).

需要一个字符。

该部分的正确代码应该是:

char* myStr1 = new char [26]; // One more than the actual string length
strcpy(myStr1, "The dog on the farm goes ");

要连接 C 字符串,算法可以是:

  1. 测量两个字符串的长度n1n2(withstrlen
  2. 为目标缓冲区分配 n1+n2+1 个字符(C 字符串终止符需要 +1
  3. strcpy 缓冲区开头的第一个字符串
  4. strcat第二个字符串到缓冲区(*)
  5. delete[] 原始字符串缓冲区的内存 如果不需要它们(这是否正确取决于谁是 "owner" 的字符串...这部分很棘手,因为 C 字符串接口没有指定)。

(*) 这不是最有效的方法。 strcat 将遍历字符串的所有字符以找到它结束的位置,但是您已经知道第一个字符串的长度是 n1 并且也可以使用 strcpy 来完成连接选择正确的开始 buffer+n1。如果您知道 strcpy 的计数,则可以在任何地方使用 memcpy 而不是 strcpy 更好,因为 strcpy 必须检查每个字符是否为 NUL 终止符。然而,在进行这种优化之前,您应该清楚地了解事情是如何工作的……只有当字符串连接代码正确并且对您来说完全显​​而易见时,您才有权开始考虑优化.

PS:一旦你获得了所有这些正确、有效和高效,你就会意识到使用 std::string 对象有多大的简化,所有这些复杂的代码都变成了 s1+s2.