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

时间:2016-10-09 05:58:27

标签: c++ pass-by-reference dynamic-arrays c-strings strcat

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

我的问题是如何使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
}

谢谢!

2 个答案:

答案 0 :(得分:1)

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

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

首先分配25个字符,然后忽略指向该分配区域的指针(技术术语是“泄漏它”)并将myStr1设置为指向字符串文字。

该代码应该使用strcpy代替从字符串文字复制到分配的区域。除了字符串是25个字符,因此您需要为至少26个空间分配空间,因为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的长度(使用strlen
  2. 为目标缓冲区分配n1+n2+1个字符(C字符串终结符需要+1
  3. strcpy缓冲区开头的第一个字符串
  4. strcat第二个字符串到缓冲区(*)
  5. delete[]原始字符串的内存缓冲如果不需要(如果这是正确的做法取决于谁是字符串的“所有者”。 ..这部分很棘手,因为C字符串接口没有指定)。
  6. (*)这不是最有效的方式。 strcat将遍历字符串的所有字符以查找其结束位置,但您已经知道第一个字符串长度为n1,并且可以使用strcpy来完成连接选择正确的开头为buffer+n1。如果你知道计数为strcpy,那么你可以在任何地方使用memcpy而不是strcpy更好地检查每个字符是NUL终止符。在进行这种优化之前,你应该清楚地理解事情是如何工作的......只有在字符串连接代码正确并且完全明显之后,你才有权开始考虑优化。

    PS:一旦你完成所有这些正确,有效和高效的工作,你就会明白使用std::string对象的简化程度,其中所有这些复杂的代码都只是s1+s2

答案 1 :(得分:0)

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

当然,复制会导致另一个问题,因为您似乎忘记了C字符串需要额外的字符作为终结符。因此,一个包含5个字符的C字符串需要六个字符的空间。

至于你的连接功能,你也需要在这里复制。为两个字符串分配足够的空间 plus 一个终止符。然后将第一个字符串复制到新内存的开头,并将第二个字符串复制到最后。

你需要为你分配的内存提供一个临时指针变量,否则“会消灭str1的原始内容”(严格来说不是这样,你只需将str1指向其他地方,丢失原始指针)。