如何连接一个std::字符串和一个int

我以为这会很简单,但它提出了一些困难。如果我有

std::string name = "John";
int age = 21;

如何组合它们以获得单个字符串"John21"

779148 次浏览

常见答案:itoa()

itoa是非标准的,正如这里所指出的。

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string itos(int i) // convert int to string
{
stringstream s;
s << i;
return s.str();
}

无耻地从http://www.research.att.com/~bs/bs_faq2.html窃取。

#include <iostream>
#include <sstream>


std::ostringstream o;
o << name << age;
std::cout << o.str();

如果您有Boost,您可以使用boost::lexical_cast<std::string>(age)将整数转换为字符串。

另一种方法是使用字符串流:

std::stringstream ss;
ss << age;
std::cout << name << ss.str() << std::endl;

第三种方法是使用C库中的sprintfsnprintf

char buffer[128];
snprintf(buffer, sizeof(buffer), "%s%d", name.c_str(), age);
std::cout << buffer << std::endl;

其他海报建议使用itoa。这不是标准函数,因此如果您使用它,您的代码将无法移植。有编译器不支持它。

#include <string>
#include <sstream>
using namespace std;
string concatenate(std::string const& name, int i)
{
stringstream s;
s << name << i;
return s.str();
}

在我看来,最简单的答案是使用sprintf函数:

sprintf(outString,"%s%d",name,age);

如果您使用MFC,则可以使用CString

CString nameAge = "";
nameAge.Format("%s%d", "John", 21);

管理C++ 字符串格式化程序.

#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;

谷歌了[和测试:p]

std::ostringstream是一个很好的方法,但有时这个额外的技巧可能会很方便地将格式转换为单行代码:

#include <sstream>
#define MAKE_STRING(tokens) /****************/ \
static_cast<std::ostringstream&>(          \
std::ostringstream().flush() << tokens \
).str()                                    \
/**/

现在你可以像这样格式化字符串:

int main() {
int i = 123;
std::string message = MAKE_STRING("i = " << i);
std::cout << message << std::endl; // prints: "i = 123"
}

按字母顺序排列:

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 the {fmt} library
result = fmt::format("{}{}", name, age);


// 6. with IOStreams
std::stringstream sstm;
sstm << name << age;
result = sstm.str();


// 7. with itoa
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + itoa(age, numstr, 10);


// 8. with sprintf
char numstr[21]; // enough to hold all numbers up to 64-bits
sprintf(numstr, "%d", age);
result = name + numstr;


// 9. 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);


// 10. with STLSoft's winstl::int_to_string()
result = name + winstl::int_to_string(age);


// 11. With Poco NumberFormatter
result = name + Poco::NumberFormatter().format(age);
  1. 安全,但速度慢;需要Boost(仅标头);大多数/所有平台
  2. 安全,需要C++11(to_string()已包含在#include <string>中)
  3. 安全,快速;需要快速格式化,必须编译;大多数/所有平台
  4. 同上
  5. 安全,快速;需要fmt库,可以编译或仅在标头模式下使用;大多数/所有平台
  6. 安全,缓慢,冗长;需要#include <sstream>(来自标准C++)
  7. 易碎(必须提供足够大的缓冲区)、快速且冗长;itoa()是非标准扩展,不能保证适用于所有平台
  8. 易碎(您必须提供足够大的缓冲区),快速且冗长;不需要任何东西(是标准C++);所有平台
  9. 易碎(必须提供足够大的缓冲区),可能是最快的转化,冗长;需要STLSoft(仅标头);大多数/所有平台
  10. 安全(您不会在单个语句中使用多个int_to_string()调用),快速;需要STLSoft(仅标头);仅限Windows
  11. 安全,但速度慢;需要PocoC++;大多数/所有平台

可以使用更多选项将整数(或其他数字对象)与字符串连接起来。它是提升格式

#include <boost/format.hpp>
#include <string>
int main()
{
using boost::format;


int age = 22;
std::string str_age = str(format("age is %1%") % age);
}

提振精神(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. Mind Karma声称是整数到字符串的最快选项转换之一。

由于一个与Qt相关的问题被关闭了,下面是如何使用Qt来完成它:

QString string = QString("Some string %1 with an int somewhere").arg(someIntVariable);
string.append(someOtherIntVariable);

字符串变量现在在末尾有一些IntVariable的值代替%1和一些其他IntVariable的值。

如果您想使用+连接任何具有输出运算符的内容,您可以提供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

这不是最有效的方法,但你不需要最有效的方法,除非你在循环中做了很多连接。

在C++11中,您可以使用std::to_string,例如:

auto result = name + std::to_string( age );

如果你有C++11,你可以使用std::to_string

示例:

std::string name = "John";
int age = 21;


name += std::to_string(age);


std::cout << name;

输出:

John21

我写了一个函数,它将整数作为参数,并将其转换为字符串文字。此函数依赖于另一个将个位数转换为其char等效值的函数:

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 holds 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 combination 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;
}

以下是如何使用IOStreams库中的解析和格式化方面将int附加到字符串的实现。

#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
}

这是最简单的方法:

string s = name + std::to_string(age);

您可以使用下面给出的简单技巧将int连接到字符串,但请注意,这仅在整数为个位数时有效。否则,将整数逐位添加到该字符串中。

string name = "John";
int age = 5;
char temp = 5 + '0';
name = name + temp;
cout << name << endl;


Output:  John5

在C++20中,你将能够做到:

auto result = std::format("{}{}", name, age);

同时您可以使用fmt库std::format基于:

auto result = fmt::format("{}{}", name, age);

免责声明:我是{fmt}库和C++20std::format的作者。

这个问题可以用很多方法来解决。我将以两种方式展示它:

  1. 使用to_string(i)将数字转换为字符串。

  2. 使用字符串流。

    代码:

    #include <string>
    #include <sstream>
    #include <bits/stdc++.h>
    #include <iostream>
    using namespace std;
    
    
    int main() {
    string name = "John";
    int age = 21;
    
    
    string answer1 = "";
    // Method 1). string s1 = to_string(age).
    
    
    string s1=to_string(age); // Know the integer get converted into string
    // where as we know that concatenation can easily be done using '+' in C++
    
    
    answer1 = name + s1;
    
    
    cout << answer1 << endl;
    
    
    // Method 2). Using string streams
    
    
    ostringstream s2;
    
    
    s2 << age;
    
    
    string s3 = s2.str(); // The str() function will convert a number into a string
    
    
    string answer2 = "";  // For concatenation of strings.
    
    
    answer2 = name + s3;
    
    
    cout << answer2 << endl;
    
    
    return 0;
    }
    
  • Std::ostringstream
#include <sstream>


std::ostringstream s;
s << "John " << age;
std::string query(s.str());
  • 圣d::to_string(C++11)
std::string query("John " + std::to_string(age));
  • 提高::lexical_cast
#include <boost/lexical_cast.hpp>


std::string query("John " + boost::lexical_cast<std::string>(age));

作为一个衬垫:name += std::to_string(age);

在C++20中,您可以有一个可变参数lambda,它可以在几行中将任意可流式类型连接到一个字符串:

auto make_string=[os=std::ostringstream{}](auto&& ...p) mutable
{
(os << ... << std::forward<decltype(p)>(p) );
return std::move(os).str();
};


int main() {
std::cout << make_string("Hello world: ",4,2, " is ", 42.0);
}

查看https://godbolt.org/z/dEe9h75eb

使用移动(os). str()保证下次调用lambda时ostringstream对象的字符串缓冲区为空。