我是C ++字符串的新手。有没有办法一次连接两个以上的字符串?或者我当时要连两个字符串?我担心的是它可能需要在每个操作上分配内存,而不是仅为最终结果分配一次。
在java中记住类似的东西,想知道std中是否存在某种方法。实际上,std :: stringstream可能是它,但我不知道它是如何工作的。
答案 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);
答案 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
可以链接+
。