现代C ++将字符串复制到char *

时间:2016-05-21 11:43:19

标签: c++ string c++11

现代的做法是什么?像<cstring>这样的标题已被弃用,某些编码样式禁止使用“类C”函数。我有三种做同样事情的方法。哪一个是现代C ++最惯用的?

1。使用迭代器并包含空终止符

{
    std::string test{"hello, world!"};
    char* output = new char[test.size() + 1];
    std::copy(test.begin(), test.end(),
        output);
    output[test.size() + 1] = '\0';
    std::cout << output;
    delete output;
}

2. 使用包含空终结符的c_str()

{
    std::string test{"hello, world!"};
    char* output = new char[test.size() + 1];
    std::copy(test.c_str(), test.c_str() + std::strlen(test.c_str()),
        output);
    std::cout << output;
    delete output;
}

3。使用std::strcpy

{
    std::string test{"hello, world!"};
    char* output = new char[test.size() + 1];
    std::strcpy(output, test.c_str());
    std::cout << output;
    delete output;
}

我不希望看起来像面试官那样说“你使用strcpy,你必须是C程序员”。

3 个答案:

答案 0 :(得分:16)

获取连续缓冲区的 modern safe pre C ++ 17方法是std::vector

std::string test{"hello, world!"};
std::vector<char> output(test.c_str(), test.c_str()+test.size()+1);
// use output.data() here...

从C ++ 17开始,std::string有一个非常量data()重载。

std::string test{"hello, world!"};
char * p = test.data();

答案 1 :(得分:11)

正确的方法是首先不使用new[]。请改用std::vector

std::string temp {"Some string"};
std::vector<char> data (begin(temp), end(temp));
// If '\0' termination is required:
data.push_back('\0');

您可以使用data访问data.data()的基础缓冲区。如果您担心由push_back引起的重新分配,您可以std::vector::reserve在分配范围之前留出足够的空间。

如果您不需要实际可修改的char数组,则可以跳过该副本,并直接使用std::string::datastd::string::c_str返回的指针。

答案 2 :(得分:1)

虽然其他答案提供了很好的建议,而且几乎在所有情况下都是正确的做法,但在某些情况下,您可能会被迫使用char*而不是容器。最常见的情况是,如果您需要直接与C代码接口,并且被调用的C方法需要非const指针(即它将取得内存的所有权)。

我将如何进行转换:

#include <string>
#include <cstdlib>

char* convert(const std::string& source)
{
    const auto result = (char*) std::malloc(source.length() + 1);
    source.copy(result, source.length());
    result[source.length()] = '\0';
    return result;
}

然后你有类似的东西:

int main()
{
    const std::string foo {"hello"};
    auto p = convert(foo);
    some_nasty_c_method(p); // promises to free p
    // other stuff
}

根据经验,如果您需要自己delete,请不要这样做;使用容器,或改为使用std::unique_ptr