Concat多个C ++字符串一次?

时间:2017-06-06 15:34:14

标签: c++ string

我是C ++字符串的新手。有没有办法一次连接两个以上的字符串?或者我当时要连两个字符串?我担心的是它可能需要在每个操作上分配内存,而不是仅为最终结果分配一次。

在java中记住类似的东西,想知道std中是否存在某种方法。实际上,std :: stringstream可能是它,但我不知道它是如何工作的。

6 个答案:

答案 0 :(得分:6)

是的,为了避免昂贵的内存浪费,请使用stringstream

  

std :: stringstream可能是它,但我不知道它是如何工作的。

这是它的工作原理:包含sstream,创建一个对象,使用流操作符<< 根据需要附加到它上面。将结果作为字符串调用函数 STR

示例:

#include <sstream>
std::stringstream mySS;

mySS << "Hello" << " World!" << "end!!" << " Foo";

当你完成时

std::string stringResult = mySS.str();

答案 1 :(得分:5)

您可以预先reserve所需空间,避免重新分配。

std::string s0{/*...*/}, s1{/*...*/}, s2{/*...*/};
std::string sink;

sink.reserve(s0.size() + s1.size() + s2.size() + 1);
sink += s0;
sink += s1;
sink += s2;

您可以使用可变参数string_cat函数使其更好。这是一个C ++ 17实现:

template <typename... Strings>
std::string string_cat(Strings&&... strings)
{
    std::string result;
    result.reserve((strings.size() + ...) + 1);
    ((result += std::forward<Strings>(strings)), ...);
    return result;
}

用法:

using namespace std::literals;
auto res = string_cat("a"s, "b"s, "c"s);

live example on wandbox

答案 2 :(得分:2)

您是正确的,每个连接可能需要分配。考虑这样的表达式,其中每个变量都是一个字符串:

std::ostringstream

这需要三个连接操作和三个临时操作,每个临时操作都需要一个新的分配。

一个简单的解决方案是使用std::ostringstream ss; ss << b << c << d << e; a = ss.str(); ,它不需要那么多的重新分配:

std::size_t total_string_size()
{
    return 1;
}

template <typename... T>
std::size_t total_string_size(std::string const &s, T const & ...tail)
{
    return s.size() + total_string_size(tail...);
}

void concat_strings_impl(std::string &) { }

template <typename... T>
void concat_strings_impl(std::string &out, std::string const &s, T const & ...tail)
{
    out += s;
    concat_strings_impl(out, tail...);
}

template <typename... T>
void concat_strings(std::string &out, T const & ...strings)
{
    out.clear();
    out.reserve(total_string_size(strings...));
    concat_strings_impl(out, strings...);
}

但是,如果我们只连接字符串,我们可以做得更好,并分配完全正确的字符串大小(C ++ 11兼容的实现):

concat_strings(a, b, c, d, e)

现在我们可以调用a = b + c + d + e;在单个重新分配中执行等效的margin-left : auto; margin-right : auto; 。 (https://github.com/dingo/api

答案 3 :(得分:2)

避免多次分配的唯一方法是告诉字符串在连接之前需要多大。

例如,要将存储在向量中的所有字符串(如列表)连接在一起:

std::string join(std::vector<std::string> const& v)
{
    std::string r; // return string

    // add up all the string sizes
    std::size_t size = 0;
    for(auto const& s: v)
        size += s.size();

    // reserve that much space all at once (one allocation)
    r.reserve(size);

    // now do the concatenations
    for(auto const& s: v)
        r += s;

    return r;
}

答案 4 :(得分:1)

可以连接多个字符串 - 没问题:

std::string hello = "Hello";
std::string cruel = "cruel";
std::string world = "world";
std::string result = hello + " " + cruel + " " + world;

结果result持有字符串&#34; Hello cruel world&#34;。

答案 5 :(得分:1)

如果你使用的是c风格的字符串(即<meta name="viewport" content="width=device-width, initial-scale=1.0"> ),那么你可以分配一次并且cat多次。 char*函数将指向目标地址的指针作为第一个参数。因此,如果您使目标字符串足够大,则只有一个alloc。因此

strcat

另一方面,如果您使用char* dest = new char[100]; dest[0] = 0; //Zero length string to start strcat(dest, str1); strcat(dest, str2); strcat(dest, str3); ,则std::string可以链接+