使用 char* 指针复制 std::string 的一部分

3

假设我有这样一段C++代码:

char* str;
std::string data = "This is a string.";

我需要复制字符串 data(除第一个和最后一个字符外)到 str 中。 我的解决方案是创建一个子串,然后执行以下操作 std::copy

std::string substring = data.substr(1, size - 2);
str = new char[size - 1];
std::copy(substring.begin(), substring.end(), str);
str[size - 2] = '\0';

但是可能这有点过度设计,因为我创建了一个新的字符串。有没有更简单的方法来实现这个目标?也许在 std:copy 调用中使用 偏移量 可以达到这个目的?

谢谢


1
如果字符串长度大于1,则可以从.begin()+1复制到.end()-1 - paolo
3
如果适用于您的应用程序,您可以使用substring.c_str()。或者必须要使用new[]进行分配吗? - user253751
我会使用成员函数std::string::copy,它可以将子字符串复制到char *中。 - chi
1
为什么需要动态创建一个新字符串?为什么不创建另一个较小的std::string,并将c_str()传递给您正在接口化的任何函数?或者如果该函数修改字符串-- std::string smallerString; ... some_c_func(&smallerString[0]); - PaulMcKenzie
我需要复制这个字符串。可能是一个XY问题。你为什么需要首先使用C风格的字符串? - n. m.
你能使用C++17吗?它有std::string_view - Marek R
2个回答

1
如上所述,你应该考虑将子字符串保留为std::string,并在需要访问底层字符时使用c_str()方法。 然而-
如果你必须通过new创建新字符串作为动态char数组,可以使用以下代码。
它检查data是否足够长,如果是,则为str分配内存,并使用std::copy类似于你的代码,但使用适应的迭代器注意:不需要为子字符串分配临时std::string代码:
#include <string>
#include <iostream>

int main() 
{
    std::string data = "This is a string.";
    auto len = data.length();
    char* str = nullptr;
    if (len > 2)
    {
        auto new_len = len - 2;
        str = new char[new_len+1];  // add 1 for zero termination
        std::copy(data.begin() + 1, data.end() - 1, str);  // copy from 2nd char till one before the last
        str[new_len] = '\0';  // add zero termination
        std::cout << str << std::endl;

       // ... use str

       delete[] str;    // must be released eventually
    }
}

输出:

his is a string

如果条件'if (len> 2)'失败,删除表'delete [] str;'的目的是什么? - Jacek
在这种情况下,str 将保持为 nullptr,而 delete 将什么也不做。但我同意最好在 if 内部执行以匹配分配和释放。已更新我的答案。 - wohlstad

0

这里有:

int length = data.length() - 1;
memcpy(str, data.c_str() + 1, length);
str[length] = 0; 

这将复制从位置 [1](而不是[0])开始的数据字符串,并保持复制,直到复制了 length() - 1 个字节。 (-1是因为您想省略第一个字符)。

然后,最终字符将被覆盖为终止字符 \0,从而完成字符串并丢弃最终字符。

当然,如果字符串没有至少一个字符,则此方法将会引起问题,因此您应该事先检查该条件。


它不会在末尾放置\0。最好只是使用memcpy或std::copy。 - user253751
嗯...你说得对。我忘记了那个。 - Refugnic Eternium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接