如何连接 std: : string 和 int?

I thought this would be really simple but it's presenting some difficulties. If I have

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

How do I combine them to get a single string "John21"?

转载于:https://stackoverflow.com/questions/191757/how-to-concatenate-a-stdstring-and-an-int

csdnceshi61
derek5. Let me add to this: I tried 'str = "hi"; str += 5; cout << str;' and saw no effect. Turns out this calls operator+=(char) and adds a non-printable character.
接近 6 年之前 回复

29个回答

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

If you have Boost, you can convert the integer to a string using boost::lexical_cast<std::string>(age).

Another way is to use stringstreams:

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

A third approach would be to use sprintf or snprintf from the C library.

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

Other posters suggested using itoa. This is NOT a standard function, so your code will not be portable if you use it. There are compilers that don't support it.

csdnceshi59
ℙℕℤℝ I see no occurence of sprintf in the answer, only snprintf.
大约 7 年之前 回复
csdnceshi59
ℙℕℤℝ an update on snprintf: it is included in C++11.
大约 7 年之前 回复
csdnceshi80
胖鸭 note that snprintf is equally non-standard c++ (like itoa which you mention). it's taken from c99
11 年多之前 回复
csdnceshi73
喵-见缝插针 My tendency would be to never use sprintf, since this can result in buffer-overflows. The example above is a good example where using sprintf would be unsafe if the name was very long.
接近 12 年之前 回复
csdnceshi68
local-host Note that snprintf is not guaranteed to null-terminate the string. Here's one way to make sure it works: <pre> char buffer[128]; buffer[sizeof(buffer)-1] = '\0'; snprintf(buffer, sizeof(buffer)-1, "%s%d", name.c_str(), age); std::cout << buffer << std::endl; </pre>
接近 12 年之前 回复

If you'd like to use + for concatenation of anything which has an output operator, you can provide a template version of operator+:

template <typename L, typename R> std::string operator+(L left, R right) {
  std::ostringstream os;
  os << left << right;
  return os.str();
}

Then you can write your concatenations in a straightforward way:

std::string foo("the answer is ");
int i = 42;
std::string bar(foo + i);    
std::cout << bar << std::endl;

Output:

the answer is 42

This isn't the most efficient way, but you don't need the most efficient way unless you're doing a lot of concatenation inside a loop.

csdnceshi56
lrony* You are right (I just tested it...). And when I tried to do something like string s = 5 + 7, I got the error invalid conversion from ‘int’ to ‘const char’*
4 年多之前 回复
weixin_41568110
七度&光 The operator returns a std::string, so wouldn't be a candidate in expressions where a string isn't convertible into the needed type. E.g., this operator+ isn't eligible to be used for + in int x = 5 + 7;. All things considered, I wouldn't define an operator like this without a very compelling reason, but my aim was to offer an answer different from the others.
4 年多之前 回复
csdnceshi56
lrony* If I try to add to integers or an integer and a double, will this function be called ? I am wondering if this solution will override the usual additions...
4 年多之前 回复

If you are using MFC, you can use a CString

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

Managed C++ also has a string formatter.

If you want to get a char* out, and have used stringstream as per what the above respondants have outlined, then do e.g.:

myFuncWhichTakesPtrToChar(ss.str().c_str());

Since what the stringstream returns via str() is a standard string, you can then call c_str() on that to get your desired output type.

Here is an implementation of how to append an int to a string using the parsing and formatting facets from the IOStreams library.

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

Shamelessly stolen from http://www.research.att.com/~bs/bs_faq2.html.

weixin_41568126
乱世@小熊 return by value is ok even though the string object has gone out of scope, stackoverflow.com/a/3977119/5393174
接近 2 年之前 回复
weixin_41568126
乱世@小熊 but s is a stack variables, the memory of s will be free after invoke itos. s should allocate from heap, and free after using, right?
接近 2 年之前 回复
weixin_41568127
?yb? thanks for the code, link is broken now :D
3 年多之前 回复

This is the easiest way:

string s = name + std::to_string(age);
csdnceshi67
bug^君 This is a post-C++11 solution!
大约 5 年之前 回复

Herb Sutter has a good article on this subject: "The String Formatters of Manor Farm". He covers Boost::lexical_cast, std::stringstream, std::strstream (which is deprecated), and sprintf vs. snprintf.

The std::ostringstream is a good method, but sometimes this additional trick might get handy transforming the formatting to a one-liner:

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

Now you can format strings like this:

int main() {
    int i = 123;
    std::string message = MAKE_STRING("i = " << i);
    std::cout << message << std::endl; // prints: "i = 123"
}
csdnceshi69
YaoRaoLov Ick. I think I'd rather use an inline function, thank you.
11 年多之前 回复
共29条数据 首页 2 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问