C样式字符串和c ++ std :: string的函数

时间:2013-11-20 21:28:58

标签: c++ c string buffer move-semantics

我有一个操作字符串的函数,我需要它来处理两种C风格的字符串,而C ++ std :: string:

// C-style overload
void TransformString(const char *in_c_string, char *out_string);
// C++ std::strings overload
std::string TransformString(const std::string &in_string);

为了避免冗余代码,我只能在其中一个中实现实际算法,然后让另一个调用它。因此,如果将实现放在C ++重载函数中,那么C风格的函数将如下所示:

void TransformString(const char *in_c_string, char * out_c_string) {
   std::string in_string(in_c_string);
   std::string out_string = TransformString(in_string); // call C++ std::string overload
   strcpy(out_c_string, out_string.c_str()); // unwanted memory copy
}

我的问题是:我是否可以这样做(只在一个函数中实现算法)而没有额外的副本(从std::string内部缓冲区到C风格的字符串)?我的第一个想法是尝试“窃取”缓冲区,就像字符串移动构造函数那样,但是在搜索Web时,看起来没有安全的方法来执行此操作,因为它是特定于实现的。如果我在C风格函数中编写算法,问题与C ++函数中的问题相同,我必须为char*字符串分配空间,然后将其移动到std::string对象。
我必须提一下,在转换完成之前,我不知道结果字符串的大小。

谢谢。

修改

这里缓冲区的大小不是问题(我知道最大大小,函数接收分配的缓冲区)。 我不能只返回std :: string.c_str(),因为当std :: string对象被销毁时(刚好在返回之后),缓冲区将变为无效。 我已经更改了变量out_c_string的名称。 (感谢0x499602D2)

2 个答案:

答案 0 :(得分:2)

只要知道输出缓冲区需要多大,就可以创建std::string并将其大小调整为缓冲区大小。然后,您可以将指向std::string缓冲区的指针传递给C风格的重载。

#include <cstring>
#include <iostream>
#include <string>

void TransformString(const char *in_c_string, char *out_c_string) {
    size_t length = strlen(in_c_string);

    for (size_t i = 0; i < length; ++i)
        out_c_string[i] = '*';

    out_c_string[length] = 'a';
    out_c_string[length+1] = 'b';
    out_c_string[length+2] = 'c';
    out_c_string[length+3] = '\0';
}

std::string TransformString(const std::string &in_string) {
    std::string out;
    out.resize(100);

    TransformString(in_string.c_str(), &out[0]);
    out.resize(strlen(&out[0]));

    // IIRC there are some C++11 rule that allows 'out' to
    // be automatically moved here (if it isn't RVO'd)
    return out;
}

int main() {
    std::string string_out = TransformString("hello world");

    char charstar_out[100];
    TransformString("hello world", charstar_out);

    std::cout << string_out << "\n";
    std::cout << charstar_out << "\n";

    return 0;
}

以下是一个实例:http://ideone.com/xwVWCh

答案 1 :(得分:-2)

您可以尝试使用c_str()从字符串类中获取c样式字符串。您必须执行const_cast<char*>才能删除const。

这只有在您不需要重新分配字符串(保持相同大小)时才有效。