我是C++字符串的新手。有沒有辦法一次連接兩個以上的字符串?或者我必須在兩個字符串連接?我擔心的是,它可能需要爲每個操作分配內存,而不是隻爲最終結果分配一次內存。一次Concat多個C++字符串?
在java中記住類似的東西,想知道std中是否有某種方法。實際上,std :: stringstream可能是它,但我不知道它是如何工作的。
我是C++字符串的新手。有沒有辦法一次連接兩個以上的字符串?或者我必須在兩個字符串連接?我擔心的是,它可能需要爲每個操作分配內存,而不是隻爲最終結果分配一次內存。一次Concat多個C++字符串?
在java中記住類似的東西,想知道std中是否有某種方法。實際上,std :: stringstream可能是它,但我不知道它是如何工作的。
是,以避免昂貴的浪費內存使用stringstream
的std :: stringstream的可能是的,但我不知道它的工作原理。
這是它如何工作的:包括sstream,創建一個對象,附加到它,就像你需要用流運算符< <得到的結果作爲字符串調用函數STR
例如:
#include <sstream>
std::stringstream mySS;
mySS << "Hello" << " World!" << "end!!" << " Foo";
,當你完成
std::string stringResult = mySS.str();
因此,它實際上保持所有字符串,直到.str()調用?這是我想知道的。謝謝。 –
確切地說,你追加和追加的東西,直到你需要它,然後調用str()....或多或少像在Java中的StringBuilder .... –
對不起,有一個額外的問題,我不知道怎麼才能真正檢查它是否像那樣工作。在調試器中打開它我猜? –
您可以在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);
您可以連接多個字符串 - 沒問題:
std::string hello = "Hello";
std::string cruel = "cruel";
std::string world = "world";
std::string result = hello + " " + cruel + " " + world;
結果result
持有字符串 「Hello殘酷的世界」。
如果您使用的是C風格的字符串(即char*
),那麼您可以分配一次並捕捉多次。 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
然後+
可以鏈接string1 + string2 + string3
。
看起來他的問題是關於多重連接的表現 - 它是否爲鏈中的每個步驟創建了一個新的中間字符串,而不是一次將它們全部組合起來? – Barmar
當心[Schlemiel the Painter](https://en.wikichip.org/wiki/schlemiel_the_painter%27s_algorithm)。 –
你是正確的,每個連接可能需要分配。考慮這樣一個表達式,其中每個變量是一個字符串:
a = b + c + d + e;
這需要三個級聯的操作和三個臨時對象,其每一個都需要一個新的分配。
一個簡單的解決方案是使用std::ostringstream
,這不應該要求儘可能多的重新分配:
std::ostringstream ss;
ss << b << c << d << e;
a = ss.str();
然而,如果我們串聯只有字符串,我們可以做的更好,並分配正好串的大小合適(C++ 11兼容的實施):
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...);
}
現在我們可以調用concat_strings(a, b, c, d, e)
在單個重新分配執行a = b + c + d + e;
等效。 (Demo)
避免多次分配的唯一方法是告訴字符串在連接之前需要變得有多大。
例如,一起加入存儲在向量的所有字符串(如列表):
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;
}
除非你有導致不(你異型,發現性能不合格),只要用'運營商+'像:'auto foo = string1 + string2 +「一些文本」+ string3;' – NathanOliver
你只是想協調一堆隨機字符串嗎?如果是這樣,那麼只需使用「+」運算符。 –