正如我们所知,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
}
谢谢!
答案 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字符串的连接,算法可以是:
n1
和n2
的长度(使用strlen
)n1+n2+1
个字符(C字符串终结符需要+1
)strcpy
缓冲区开头的第一个字符串strcat
第二个字符串到缓冲区(*)delete[]
原始字符串的内存缓冲如果不需要(如果这是正确的做法取决于谁是字符串的“所有者”。 ..这部分很棘手,因为C字符串接口没有指定)。(*)这不是最有效的方式。 strcat
将遍历字符串的所有字符以查找其结束位置,但您已经知道第一个字符串长度为n1
,并且可以使用strcpy
来完成连接选择正确的开头为buffer+n1
。如果你知道计数为strcpy
,那么你可以在任何地方使用memcpy
而不是strcpy
更好地检查每个字符是NUL
终止符。在进行这种优化之前,你应该清楚地理解事情是如何工作的......只有在字符串连接代码正确并且完全明显之后,你才有权开始考虑优化。
PS:一旦你完成所有这些正确,有效和高效的工作,你就会明白使用std::string
对象的简化程度,其中所有这些复杂的代码都只是s1+s2
。
答案 1 :(得分:0)
您分配内存并使指针指向该内存。然后你覆盖指针,使它们指向其他地方。例如, myStr1
使变量指向字符串文字而不是您分配的内存。您需要将字符串复制到已分配的内存中。
当然,复制会导致另一个问题,因为您似乎忘记了C字符串需要额外的字符作为终结符。因此,一个包含5个字符的C字符串需要六个字符的空间。
至于你的连接功能,你也需要在这里复制。为两个字符串分配足够的空间 plus 一个终止符。然后将第一个字符串复制到新内存的开头,并将第二个字符串复制到最后。
你需要为你分配的内存提供一个临时指针变量,否则“会消灭str1的原始内容”(严格来说不是这样,你只需将str1
指向其他地方,丢失原始指针)。