An̲*_*rew 164 c++ stl string-concatenation
是否有C++标准模板库类提供有效的字符串连接功能,类似于C#的StringBuilder或Java的StringBuffer?
jk.*_*jk. 143
C++的方式是使用std :: stringstream或只是普通的字符串连接.C++字符串是可变的,因此连接的性能考虑因素不太重要.
关于格式化,您可以在流上执行所有相同的格式设置,但以不同的方式,类似于cout.或者你可以使用一个强类型的函子来封装它并提供一个String.Format之类的接口,例如boost :: format
Stu*_*Stu 84
std :: string.append函数不是一个好选项,因为它不接受多种形式的数据.更有用的替代方法是使用std:stringstream,如下所示:
#include <sstream>
// ...
std::stringstream ss;
//put arbitrary formatted data into the stream
ss << 4.5 << ", " << 4 << " whatever";
//convert the stream buffer into a string
std::string str = ss.str();
Run Code Online (Sandbox Code Playgroud)
iai*_*ain 50
注意这个答案最近受到了一些关注.我不是在提倡这个解决方案(这是我过去在STL之前看到的解决方案).这是一种有趣的方法,只应该应用于std::string或者std::stringstream如果在对代码进行分析之后,您会发现这会带来改进.
我通常使用std::string或std::stringstream.我从来没有遇到任何问题.如果我事先知道字符串的粗略大小,我通常会先保留一些房间.
我看到其他人在遥远的过去制作了自己的优化字符串构建器.
class StringBuilder {
private:
std::string main;
std::string scratch;
const std::string::size_type ScratchSize = 1024; // or some other arbitrary number
public:
StringBuilder & append(const std::string & str) {
scratch.append(str);
if (scratch.size() > ScratchSize) {
main.append(scratch);
scratch.resize(0);
}
return *this;
}
const std::string & str() {
if (scratch.size() > 0) {
main.append(scratch);
scratch.resize(0);
}
return main;
}
};
Run Code Online (Sandbox Code Playgroud)
它使用两个字符串,一个用于大多数字符串,另一个用作连接短字符串的临时区域.它通过将短附加操作批处理为一个小字符串然后将其附加到主字符串来优化附加,从而减少主字符串变大时所需的重新分配数量.
我没有用std::string或要求这个技巧std::stringstream.我认为它在std :: string之前与第三方字符串库一起使用,就在很久以前.如果你采用这样的策略,首先应用你的应用程序.
And*_*lam 10
您可以使用.append()来简单地连接字符串.
std::string s = "string1";
s.append("string2");
Run Code Online (Sandbox Code Playgroud)
我想你甚至可以做到:
std::string s = "string1";
s += "string2";
Run Code Online (Sandbox Code Playgroud)
至于C#的格式化操作StringBuilder,我相信snprintf(或者sprintf如果你想冒险编写错误的代码;-))进入字符数组并转换回字符串是唯一的选择.
一个方便的 C++ 字符串生成器
就像之前回答的许多人一样,std::stringstream 是首选方法。它运行良好,并有很多转换和格式选项。IMO 但它有一个非常不方便的缺陷:你不能将它用作单衬或表达。你总是要写:
std::stringstream ss;
ss << "my data " << 42;
std::string myString( ss.str() );
Run Code Online (Sandbox Code Playgroud)
这很烦人,尤其是当您想在构造函数中初始化字符串时。
原因是,a) std::stringstream 没有到 std::string 的转换运算符,并且 b) stringstream 的运算符 << () 不返回 stringstream 引用,而是返回 std::ostream 引用- 不能作为字符串流进一步计算。
解决方案是覆盖 std::stringstream 并为其提供更好的匹配运算符:
namespace NsStringBuilder {
template<typename T> class basic_stringstream : public std::basic_stringstream<T>
{
public:
basic_stringstream() {}
operator const std::basic_string<T> () const { return std::basic_stringstream<T>::str(); }
basic_stringstream<T>& operator<< (bool _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (char _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (signed char _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (unsigned char _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (short _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (unsigned short _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (int _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (unsigned int _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (long _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (unsigned long _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (long long _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (unsigned long long _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (float _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (double _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (long double _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (void* _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (std::streambuf* _val) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (std::ostream& (*_val)(std::ostream&)) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (std::ios& (*_val)(std::ios&)) { std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (std::ios_base& (*_val)(std::ios_base&)){ std::basic_stringstream<T>::operator << (_val); return *this; }
basic_stringstream<T>& operator<< (const T* _val) { return static_cast<basic_stringstream<T>&>(std::operator << (*this,_val)); }
basic_stringstream<T>& operator<< (const std::basic_string<T>& _val) { return static_cast<basic_stringstream<T>&>(std::operator << (*this,_val.c_str())); }
};
typedef basic_stringstream<char> stringstream;
typedef basic_stringstream<wchar_t> wstringstream;
}
Run Code Online (Sandbox Code Playgroud)
有了这个,你可以写这样的东西
std::string myString( NsStringBuilder::stringstream() << "my data " << 42 )
Run Code Online (Sandbox Code Playgroud)
即使在构造函数中。
我必须承认我没有测量性能,因为我还没有在大量使用字符串构建的环境中使用它,但我认为它不会比 std::stringstream 差多少,因为一切都已完成通过引用(除了转换为字符串,但这也是 std::stringstream 中的复制操作)
因为std::string在C++中是可变的,你可以使用它.它具有+= operator和append功能.
如果需要附加数值数据,请使用这些std::to_string函数.
如果您希望以能够将任何对象序列化为字符串的形式提供更大的灵活性,那么请使用std::stringstream该类.但是您需要实现自己的流操作符函数才能使用自己的自定义类.