std :: string과 int를 연결하는 방법은 무엇입니까?


655

나는 이것이 매우 간단하다고 생각했지만 어려움을 겪고 있습니다. 만약 내가 가지고 있다면

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

단일 문자열을 얻기 위해 어떻게 결합 "John21"합니까?


Herb Sutter는이 주제에 대한 좋은 기사를 가지고 있습니다 : "매너 팜의 문자열 포맷터" . 그는 포함 Boost::lexical_cast, std::stringstream, std::strstream(사용되지 않은), 및 sprintfsnprintf.
Fred Larson

이것에 덧붙여 보자 : 'str = "hi"; str + = 5; cout << str; ' 효과가 없습니다. 이 연산자 + = (char)를 호출하고 인쇄 할 수없는 문자를 추가합니다.
daveagp

답변:


1126

알파벳 순서로 :

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. 안전하지만 느리다. 부스트 가 필요합니다 (헤더 만). 대부분 / 모든 플랫폼
  2. 안전하고 C ++ 11이 필요합니다 ( to_string () 은 이미 포함되어 있습니다 #include <string>)
  3. 안전하고 빠릅니다. 컴파일 해야하는 FastFormat이 필요 합니다. 대부분 / 모든 플랫폼
  4. ( 상동 )
  5. 안전하고 빠릅니다. {fmt} 라이브러리 가 필요합니다. 이 라이브러리 는 헤더 전용 모드로 컴파일하거나 사용할 수 있습니다. 대부분 / 모든 플랫폼
  6. 안전하고 느리고 장황한; 필요 #include <sstream>(표준 C ++에서)
  7. 부서지기 쉬우 며 (충분히 큰 버퍼를 제공해야 함) 빠르고 상세합니다. itoa ()는 비표준 확장이며 모든 플랫폼에서 사용 가능한 것은 아닙니다
  8. 부서지기 쉬우 며 (충분히 큰 버퍼를 제공해야 함) 빠르고 상세합니다. 아무것도 요구하지 않습니다 (표준 C ++). 모든 플랫폼
  9. 취성입니다 (충분히 큰 버퍼를 제공해야 함), 아마도 가장 빠른 변환이 가능합니다 . STLSoft (헤더 전용) 가 필요합니다 . 대부분 / 모든 플랫폼
  10. safe-ish ( 단일 명령문에서 둘 이상의 int_to_string () 호출을 사용하지 않음 ), 빠름; STLSoft (헤더 전용) 가 필요합니다 . Windows 전용
  11. 안전하지만 느리다. Poco C ++ 필요 ; 대부분 / 모든 플랫폼

13
당신이 gfiven 한 하나의 링크를 제외하고, 당신은 당신의 퍼포먼스 코멘트에 어떤 근거를두고 있습니까?
JamieH

2
그것은 하나의 대답으로 거의 당신의 명성입니다! 운이 좋은 콩;) 8은 표준 C (물론 C ++)이지만 차별화 할 가치가 있다고 생각합니다.
noelicus

std :: to_string (age)는 결과에 추가되는 임시 문자열을 생성하므로 속도가 느립니다.
Igor Bukanov

Arduino를 사용하는 경우을 사용할 수도 있습니다 String(number).
Machado

267

C ++ 11에서는 다음과 같이 사용할 수 있습니다 std::to_string.

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

나는 이것을 좋아한다. 단순하다. 감사.
truthadjustr

85

Boost가있는 경우을 사용하여 정수를 문자열로 변환 할 수 있습니다 boost::lexical_cast<std::string>(age).

다른 방법은 문자열 스트림을 사용하는 것입니다.

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

세 번째 방법은 C 라이브러리 를 사용 sprintf하거나 snprintfC 라이브러리에서 사용하는 것 입니다.

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

다른 포스터는을 사용하도록 제안했습니다 itoa. 이것은 표준 기능이 아니므로 사용하면 코드를 이식 할 수 없습니다. 이를 지원하지 않는 컴파일러가 있습니다.


snprintf는 문자열을 null로 종료한다고 보장하지 않습니다. 작동하는지 확인하는 방법은 다음과 같습니다. <pre> char buffer [128]; 버퍼 [sizeof (버퍼) -1] = '\ 0'; snprintf (버퍼, sizeof (버퍼) -1, "% s % d", name.c_str (), 나이); std :: cout << 버퍼 << std :: endl; </ pre>
Mr Fooz

sprintf를 사용하지 않는 경향이 있습니다. 버퍼 오버플로가 발생할 수 있기 때문입니다. 위의 예는 이름이 매우 긴 경우 sprintf 사용이 안전하지 않은 좋은 예입니다.
terson

snprintf는 비표준 C ++과 같습니다 (당신이 언급 한 itoa와 같습니다). 그것은 C99에서 가져온 것
요하네스 SCHAUB - litb

@ terson : 나는 sprintf대답에서 발생하지 않는 것을 본다 snprintf.
David Foerster


52
#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 에서 뻔뻔스럽게 도난당했습니다 .


그러나 s 스택 변수이며 sinvoke 후 메모리가 해제 됩니다 itos. s힙에서 할당하고 free사용 후 바로 할당해야 합니까?
kgbook

1
값으로 반환 문자열 개체가 범위 밖으로 사라 졌더라도 괜찮 stackoverflow.com/a/3977119/5393174
kgbook

32

가장 쉬운 방법입니다.

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

8
이것은 C ++ 11 이후의 솔루션입니다!
YamHon.CHAN

23

C ++ 11이 있다면를 사용할 수 있습니다 std::to_string.

예:

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

name += std::to_string(age);

std::cout << name;

산출:

John21

2
여기서name += std::to_string(static_cast<long long>(age)); 볼 수 있듯이 VC ++ 2010에 있을 것 입니다.
neonmate

@neonmate name += std::to_string(age + 0LL);대신에 어떻습니까?
chux-복원 Monica Monica

18

가장 간단한 대답은 sprintf함수 를 사용하는 것 같습니다.

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

1
snprintf는 까다로울 수 있지만 (주로 특정 상황에서 null 문자를 포함 할 수 없기 때문에) sprintf 버퍼 오버플로로 인해 잠재적 인 문제가 발생하지 않도록 선호합니다.
terson

3
std :: string을 % s에 전달하면 일부 버전의 컴파일러에서 sprintf (char *, const char *, ...)가 실패합니다. 그러나 모두는 아니지만 (정의되지 않은 동작) 문자열 길이 (SSO)에 따라 달라질 수 있습니다. .c_str ()를 사용하십시오
MSalters

플러스 sprintf는 버퍼 오버 플로우의 영향을받을 수 있으므로 코드 삽입이 가능합니다.
Jean-François Fabre

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

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

Googled [및 테스트 : p]


10

이 문제는 여러 가지 방법으로 수행 할 수 있습니다. 두 가지 방법으로 보여 드리겠습니다.

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

어느 것이 더 빠릅니까?
최규현

7

+출력 연산자가있는 것을 연결하는 데 사용하려면 다음과 같은 템플릿 버전을 제공 할 수 있습니다 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

이것은 가장 효율적인 방법은 아니지만 루프 내에서 많은 연결을 수행하지 않는 한 가장 효율적인 방법은 필요하지 않습니다.


정수 또는 정수와 이중에 추가하려고하면이 함수가 호출됩니까? 이 솔루션이 일반적인 추가 기능보다 우선 적용되는지 궁금합니다.
Hilder Vitor Lima Pereira

연산자는을 반환 std::string하므로 문자열을 필요한 유형으로 변환 할 수없는 표현식의 후보가되지 않습니다. 예,이 operator+사용 할 자격이 없습니다 +에서 int x = 5 + 7;. 고려해야 할 모든 것, 나는 매우 설득력있는 이유 없이 이와 같은 연산자를 정의하지 않을 것이지만, 나의 목표는 다른 사람들과 다른 답변을 제공하는 것이 었습니다.
uckelman

당신이 맞습니다 (방금 테스트했습니다 ...). 그리고 string s = 5 + 7 과 같은 일을 시도했을 때 'int'에서 'const char '*로 잘못 변환 하는 오류가 발생했습니다.
Hilder Vitor Lima Pereira

5

MFC를 사용하는 경우 CString을 사용할 수 있습니다

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

관리되는 C ++에는 문자열 포맷터도 있습니다.


4

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

4

Qt 관련 질문이이 질문에 찬성하여 종료되었으므로 다음은 Qt를 사용하여 수행하는 방법입니다.

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

문자열 변수는 이제 % 1 대신에 someIntVariable의 값을 가지며 마지막에 someOtherIntVariable의 값을 갖습니다.


QString ( "Something") + QString :: number (someIntVariable)도 작동합니다.
gremwell

3

정수 (또는 다른 숫자 객체)를 문자열과 연결하는 데 사용할 수있는 옵션이 더 있습니다. 그것은이다 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 (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는 정수에서 문자열로 변환 하는 가장 빠른 옵션 중 하나라고 주장합니다 .



3

주어진 간단한 트릭을 사용하여 int를 문자열에 연결할 수 있지만 정수가 한 자리 수인 경우에만 작동합니다. 그렇지 않으면 해당 문자열에 숫자 단위로 정수를 추가하십시오.

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

Output:  John5

2

다음은 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
}

2
  • std :: ostringstream
#include <sstream>

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

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

어느 것이 가장 빠릅니까?
최규현

2

내가 작성한 함수가 있는데, int 숫자를 매개 변수로 사용하여 문자열 리터럴로 변환합니다. 이 함수는 한 자릿수를 해당 문자로 변환하는 다른 함수에 종속됩니다.

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

1

{FMT} 라이브러리 :

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

라이브러리의 하위 집합은 P0645 텍스트 형식 으로 표준화를 위해 제안 되었으며, 허용되는 경우 위와 같이됩니다.

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

면책 조항 : 저는 {fmt} 라이브러리의 저자입니다.


0

하나의 라이너로 : name += std::to_string(age);


3
0x499602D2 답변과 동일한 코드입니다.
BDL
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.