如何连接一个std :: string和一个int?
我认为这会很简单,但是会带来一些困难。 如果我有
std::string name = "John"; int age = 21;
我如何将他们结合起来得到一个string"John21"
?
按字母顺序排列:
std::string name = "John"; int age = 21; std::string result; // 1. with Boost result = name + boost::lexical_cast<std::string>(age); // 2. with C++11 result = name + std::to_string(age); // 3. with FastFormat.Format fastformat::fmt(result, "{0}{1}", name, age); // 4. with FastFormat.Write fastformat::write(result, name, age); // 5. with IOStreams std::stringstream sstm; sstm << name << age; result = sstm.str(); // 6. with itoa char numstr[21]; // enough to hold all numbers up to 64-bits result = name + itoa(age, numstr, 10); // 7. with sprintf char numstr[21]; // enough to hold all numbers up to 64-bits sprintf(numstr, "%d", age); result = name + numstr; // 8. with STLSoft's integer_to_string char numstr[21]; // enough to hold all numbers up to 64-bits result = name + stlsoft::integer_to_string(numstr, 21, age); // 9. with STLSoft's winstl::int_to_string() result = name + winstl::int_to_string(age); // 10. With Poco NumberFormatter result = name + Poco::NumberFormatter().format(age);
- 是安全的,但是很慢; 需要Boost (仅标题); 大多数/所有平台
- 是安全的,需要C ++ 11( to_string()已经包含在
#include <string>
) - 安全,快捷; 需要FastFormat ,它必须被编译; 大多数/所有平台
- 安全,快捷; 需要FastFormat ,它必须被编译; 大多数/所有平台
- 安全,缓慢和冗长; 需要
#include <sstream>
(来自标准的C ++) - 是脆弱的(你必须提供一个足够大的缓冲区),速度很快,而且冗长; itoa()是一个非标准扩展,并不保证可用于所有平台
- 是脆弱的(你必须提供一个足够大的缓冲区),速度很快,而且冗长; 不需要任何东西(是标准的C ++); 所有平台
- 是脆弱的(你必须提供一个足够大的缓冲区), 可能是最快可能的转换 ,详细; 需要STLSoft (仅标头); 大多数/所有平台
- safe-ish(你不要在一个语句中使用多个int_to_string()调用),快; 需要STLSoft (仅标头); 仅Windows
- 是安全的,但是很慢; 需要Poco C ++ ; 大多数/所有平台
在C ++ 11中,
std::string result = name + std::to_string (age);
如果你有Boost,你可以使用boost::lexical_cast<std::string>(age)
将整数转换为一个string。
另一种方法是使用stringstreams:
std::stringstream ss; ss << age; std::cout << name << ss.str() << std::endl;
第三种方法是使用C库中的sprintf
或snprintf
。
char buffer[128]; snprintf(buffer, sizeof(buffer), "%s%d", name.c_str(), age); std::cout << buffer << std::endl;
其他海报build议使用itoa
。 这不是一个标准函数,所以如果你使用它的话你的代码将不能移植。 有编译器不支持它。
std::ostringstream o; o << name << age; std::cout << o.str();
#include <iostream> #include <string> #include <sstream> using namespace std; string itos(int i) // convert int to string { stringstream s; s << i; return s.str(); }
这是最简单的方法:
string s = name + std::to_string(age);
在我看来,最简单的答案是使用sprintf
函数:
sprintf(outString,"%s%d",name,age);
如果你有C ++ 11,你可以使用std::to_string
:
std::string name = "John"; int age = 21; name += std::to_string(age); std::cout << name; // "John21"
我没有足够的业力去评论(更不用说编辑了),但是杰伊的post(现在是27票中的最高票)有一个错误。 此代码:
std::stringstream ss; ss << age; std::cout << name << ss.str() << std::endl;
不解决创build由连接的string和整数组成的string的陈述问题。 我认为周杰伦更像这样的东西:
std::stringstream ss; ss << name; ss << age; std::cout << "built string: " << ss.str() << std::endl;
最后一行是打印结果,并显示如何访问最终的连接string。
#include <string> #include <sstream> using namespace std; string concatenate(std::string const& name, int i) { stringstream s; s << name << i; return s.str(); }
Herb Sutter在这个问题上有一篇很好的文章: “庄园农场的string格式” 。 他涵盖了Boost::lexical_cast
, std::stringstream
, std::strstream
(已弃用)以及sprintf
与snprintf
。
#include <sstream> template <class T> inline std::string to_string (const T& t) { std::stringstream ss; ss << t; return ss.str(); }
那么你的用法看起来就像这样
std::string szName = "John"; int numAge = 23; szName += to_string<int>(numAge); cout << szName << endl;
谷歌search [和testing:P]
如果您希望使用+
来连接具有输出运算符的任何内容,则可以提供operator+
的模板版本:
template <typename L, typename R> std::string operator+(L left, R right) { std::ostringstream os; os << left << right; return os.str(); }
然后你可以直接写你的连接:
std::string foo("the answer is "); int i = 42; std::string bar(foo + i); std::cout << bar << std::endl;
输出:
the answer is 42
这不是最有效的方法,但除非在循环中进行大量的连接,否则不需要最有效的方法。
如果您使用MFC,则可以使用CString
CString nameAge = ""; nameAge.Format("%s%d", "John", 21);
托pipeC ++也有一个string格式化程序 。
常见答案: itoa()
这不好。 itoa是非标准的,正如在Linux中itoa函数的位置所指出的那样。
std :: ostringstream是一个很好的方法,但有时候这个额外的技巧可能会方便地将格式转化为一行:
#include <sstream> #define MAKE_STRING(tokens) /****************/ \ static_cast<std::ostringstream&>( \ std::ostringstream().flush() << tokens \ ).str() \ /**/
现在你可以像这样格式化string:
int main() { int i = 123; std::string message = MAKE_STRING("i = " << i); std::cout << message << std::endl; // prints: "i = 123" }
作为Qt相关的问题是closures的赞成这一个,这里是如何使用Qt做到这一点:
QString string = QString("Some string %1 with an int somewhere").arg(someIntVariable); string.append(someOtherIntVariable);
stringvariables现在具有someIntVariable的值来代替%1和someOtherIntVariable的值。
您可以通过使用给定的下面的简单技巧来将int内联到string,但是请注意,这只适用于整数是单个数字,否则将整数逐个数字添加到该string。
string name = "John"; int age = 5; char temp=5+'0'; name=name+temp; cout<<name<<endl; Output:- John5
有更多的选项可用于连接整数(或其他数字对象)与string。 它是Boost.Format
#include <boost/format.hpp> #include <string> int main() { using boost::format; int age = 22; std::string str_age = str(format("age is %1%") % age); }
和Boost.Spirit的 Karma(v2)
#include <boost/spirit/include/karma.hpp> #include <iterator> #include <string> int main() { using namespace boost::spirit; int age = 22; std::string str_age("age is "); std::back_insert_iterator<std::string> sink(str_age); karma::generate(sink, int_, age); return 0; }
Boost.Spirit Karma声称是整数到string转换的最快选项之一 。
如果你想得到一个char * out,并根据上面的回应已经概括的使用了stringstream,那么做例如:
myFuncWhichTakesPtrToChar(ss.str().c_str());
由于stringstream通过str()返回的是一个标准的string,所以你可以调用c_str()来得到你想要的输出types。
有一个我写的函数,它接受参数的int数,并将其转换为string文字,这个函数是依赖于另一个函数,将一个数字转换为它的字符相当于:
char intToChar ( int num) { if ( num < 10 && num >= 0) { return num + 48; //48 is the number that we add to an integer number to have its character equivalent (see the unsigned ASCII table) } else { return '*'; } } string intToString ( int num) { int digits = 0, process, single; string numString; process = num; //The following process the number of digits in num while ( process != 0) { single = process % 10; // single now hold the rightmost portion of the int process = (process - single)/10; // take out the rightmost number of the int ( it's a zero in this portion of the int), then divide it by 10 // The above combinasion eliminates the rightmost portion of the int digits ++; } process = num; //Fill the numString with '*' times digits for ( int i = 0; i < digits; i++) { numString += '*'; } for ( int i = digits-1; i >= 0; i-- ) { single = process % 10; numString[i] = intToChar ( single); process = ( process - single) / 10; } return numString; }
这里是一个如何将一个int附加到string的实现,使用IOStreams库中的parsing和格式化构面。
#include <iostream> #include <locale> #include <string> template <class Facet> struct erasable_facet : Facet { erasable_facet() : Facet(1) { } ~erasable_facet() { } }; void append_int(std::string& s, int n) { erasable_facet<std::num_put<char, std::back_insert_iterator<std::string>>> facet; std::ios str(nullptr); facet.put(std::back_inserter(s), str, str.fill(), static_cast<unsigned long>(n)); } int main() { std::string str = "ID: "; int id = 123; append_int(str, id); std::cout << str; // ID: 123 }
另一个简单的方法是:
name.append(age+""); cout << name;
没有C ++ 11,对于一个小整数范围,我发现这是我所需要的一切:
声明/包含以下某处的某些变体:
const string intToString[10] = {"0","1","2","3","4","5","6","7","8","9"};
然后:
string str = intToString[3]+" + "+intToString[4]+" = "+intToString[7]; //str equals "3 + 4 = 7"
也与枚举一起工作。
为像我这样可能无法访问C ++ 11和其他库/头文件(如boost)的人提供了一种替代解决scheme。 一个简单的转换就像这样:
例如数字是4,要将3转换为ASCII我们可以简单地使用代码:
char a ='0'+ 4
这将立即存储4作为一个字符在一个。
从这里,我们可以简单地连接string的其余部分。
我是初学C ++用户,发现这是最简单的方法:
cout << name << age;
这将成功连接名字和年龄,输出将是“John21”。
然而,没有人会说这个理由。 我认为可能有一个缺陷,虽然我迄今还没有经历过。
编辑:我已经意识到,这不一定是正确的答案,但是我会保持在这里,以防任何C ++初学者想知道如何输出连接的string。