9

我正在阅读 Bjarne Stroustrup 撰写的The C++ Programming Language第 3 版并尝试完成所有练习。我不确定如何处理第 6.6 节中的练习 13,所以我想我会转向 Stack Overflow 以获得一些见解。这是问题的描述:

编写一个函数cat(),它接受两个 C 风格的字符串参数并返回一个字符串,该字符串是参数的串联。使用new查找结果的存储。

到目前为止,这是我的代码,在我不确定该怎么做的地方带有问号:

? cat(char first[], char second[])
{
    char current = '';
    int i = 0;

    while (current != '\0')
    {
        current = first[i];
        // somehow append current to whatever will eventually be returned
        i++;
    }

    current = '';
    i = 0;

    while (current != '\0')
    {
        current = second[i];
        // somehow append current to whatever will eventually be returned
        i++;
    }

    return ?
}

int main(int argc, char* argv[])
{
    char first[]  = "Hello, ";
    char second[] = "World!";

    ? = cat(first, second);

    return 0;
}

这是我的问题:

  1. 如何使用new查找商店?我是否应该做类似的事情,std::string* result = new std::string;或者我应该使用new以某种方式创建另一个 C 风格的字符串?
  2. 与上一个问题相关,我应该从 cat() 返回什么?如果我必须使用new,我认为它需要是一个指针。但是指向什么的指针?
  3. 虽然问题没有提到使用delete来释放内存,但我知道我应该这样做,因为我将使用new来分配。我应该在返回之前在 main 的末尾删除吗?
4

7 回答 7

4

在“真正的”程序中,是的,你会使用 std::string。听起来这个示例希望您改用 C 字符串。

所以也许是这样的:

char * cat(char first[], char second[])
{
    char *result = new char[strlen(first) + strlen(second) + 1];

...

问:你如何“追加”?

A:只要把“first”中的所有内容都写到“result”中即可。

完成后,继续在“第二”中写入所有内容到结果(从您离开的地方开始)。完成后,请确保在末尾附加“\0”。

于 2013-07-27T23:45:11.753 回答
4

如何使用new查找商店?我是否应该做类似的事情,std::string* result = new std::string;或者我应该使用new以某种方式创建另一个 C 风格的字符串?

后者; 该方法采用 C 风格的字符串,文本中没有任何内容表明它应该返回任何其他内容。因此函数的原型应该是char* cat(char const*, char const*). 当然,这不是您通常编写函数的方式;手动内存管理在现代 C++ 中是完全禁忌的,因为它很容易出错。

虽然问题没有提到使用 delete 来释放内存,但我知道我应该这样做,因为我将使用 new 来分配。我应该在返回之前在 main 的末尾删除吗?

在这个练习中,是的。在现实世界中,不:就像我上面所说的,这完全是禁忌。实际上,您将返回 astd::string不是使用new. 如果您发现自己手动分配内存(并假设这是有充分理由的),那么您不会将该内存放在原始指针中,而是放在智能指针中 -std::unique_ptrstd::shared_ptr.

于 2013-07-27T23:45:21.053 回答
3
  1. 你应该返回一个 C 风格的字符串,所以你不能使用std::string(或者至少,这不是“本着问题的精神”)。是的,您应该使用new来制作 C 风格的字符串。
  2. 你应该返回你生成的 C 风格的字符串......所以,指向你新创建的字符串的第一个字符的指针。
  3. 正确,您应该在最后删除结果。我希望它可能会被忽略,因为在这种特殊情况下,它可能并不重要——但为了完整性/正确性,你应该这样做。
于 2013-07-27T23:46:20.337 回答
3

这是我不久前从我的一个项目中挖出的一些旧代码:

char* mergeChar(char* text1, char* text2){
    //Find the length of the first text
    int alen = 0;
    while(text1[alen] != '\0')
        alen++;

    //Find the length of the second text
    int blen = 0;
    while(text2[blen] != '\0')
        blen++;

    //Copy the first text
    char* newchar = new char[alen + blen + 1];
    for(int a = 0; a < alen; a++){
            newchar[a] = text1[a];
    }

    //Copy the second text
    for(int b = 0; b < blen; b++)
        newchar[alen + b] = text2[b];

    //Null terminate!
    newchar[alen + blen] = '\0';
    return newchar;
}

通常,在“真实”程序中,您应该使用std::string. 以后确定你delete[] newchar

于 2013-07-27T23:48:54.220 回答
2

练习的意思是new为了分配内存使用。“查找商店”的措辞很奇怪,但实际上就是这样。你告诉它你需要多少存储,它会找到你可以使用的可用内存块,并返回它的地址。

看起来练习不希望您使用 std::string。听起来您需要返回一个char*. 所以函数原型应该是:

char* cat(const char first[], const char second[]);

注意说明const符。这很重要,这样您就可以将字符串文字作为参数传递。

因此,在不立即给出代码的情况下,您需要做的是确定结果字符串应该有多大char*,使用 分配所需的数量new,将两个源字符串复制到新分配的空间中,然后返回它。

请注意,您通常不会在 C++ 中手动执行这种内存管理(而是使用std::string),但了解它仍然很重要,这就是本练习的原因。

于 2013-07-27T23:48:23.497 回答
0

似乎您需要使用new为字符串分配内存,然后返回指针。因此 的return类型cat将是`char*

你可以做这样的事情:

int n = 0;
int k = 0;

//also can use strlen
while( first[n] != '\0' )
     n ++ ;
while( second[k] != '\0' )
     k ++ ;

//now, the allocation

char* joint = new char[n+k+1]; //+1 for a '\0'

//and for example memcpy for joining

memcpy(joint, first, n );
memcpy(joint+n, second, k+1); //also copying the null


return joint;
于 2013-07-27T23:57:33.313 回答
0

它几乎是在告诉您以 C 方式执行此操作:

#include <cstring>

char *cat (const char *s1, const char *s2)
{
    // Learn to explore your library a bit, and
    // you'll see that there is no need for a loop
    // to determine the lengths. Anything C string
    // related is in <cstring>.
    //
    size_t len_s1 = std::strlen(s1);
    size_t len_s2 = std::strlen(s2);
    char *dst;

    // You have the lengths.
    // Now use `new` to allocate storage for dst.


    /*
     * There's a faster way to copy C strings
     * than looping, especially when you
     * know the lengths...
     *
     * Use a reference to determine what functions
     * in <cstring> COPY values.
     * Add code before the return statement to
     * do this, and you will have your answer.
     *
     * Note: remember that C strings are zero
     * terminated!
     */

    return dst;
}

当您释放分配的内存时,不要忘记使用正确的运算符。否则你会有内存泄漏。

快乐编码!:-)

于 2013-07-28T00:51:40.783 回答