본문 바로가기
개발/C++

C ++에서 int를 문자열로 변환하는 가장 쉬운 방법

by MinorMan 2020. 9. 30.
반응형

<질문>

C ++에서 int를 동등한 문자열로 변환하는 가장 쉬운 방법은 무엇입니까? 두 가지 방법을 알고 있습니다. 더 쉬운 방법이 있습니까?

(1)

int a = 10;
char *intStr = itoa(a);
string str = string(intStr);

(2)

int a = 10;
stringstream ss;
ss << a;
string str = ss.str();

<답변1>

C ++ 11은 std :: stoi (및 각 숫자 유형에 대한 변형) 및 std :: to_string을 도입했습니다. std :: to_string은 C atoi 및 itoa에 대응하지만 std :: string 용어로 표현됩니다.

#include  

std::string s = std::to_string(42);

따라서 제가 생각할 수있는 가장 짧은 방법입니다. auto 키워드를 사용하여 유형 이름 지정을 생략 할 수도 있습니다.

auto s = std::to_string(42);

참고 : [string.conversions] 참조 (n3242의 21.5)


<답변2>

2 년 후 @ v.oddou와의 토론을 통해 C ++ 17은 마침내 매크로 추악함을 거치지 않고 원래 매크로 기반 유형에 구애받지 않는 솔루션 (아래에 보존 됨)을 수행하는 방법을 제공했습니다.

// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    // fold expression
    ( sstr << std::dec << ... << args );
    return sstr.str();
}

용법:

int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );

원래 답변 :

"converting ... to string"은 되풀이되는 문제이므로 항상 C ++ 소스의 중앙 헤더에 SSTR () 매크로를 정의합니다.

#include 

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

사용법은 다음과 같이 쉽습니다.

int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );

위의 내용은 C ++ 98과 호환되며 (C ++ 11 std :: to_string을 사용할 수없는 경우) 타사 포함이 필요하지 않습니다 (Boost lexical_cast <>를 사용할 수없는 경우). 이 두 솔루션 모두 더 나은 성능을 제공합니다.


<답변3>

나는 일반적으로 다음 방법을 사용합니다.

#include 

template 
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

여기에 자세히 설명되어 있습니다.


<답변4>

아마도 가장 일반적인 쉬운 방법은 기본적으로 두 번째 선택을 Boost의 템플릿과 같은 lexical_cast라는 템플릿으로 래핑하므로 코드는 다음과 같습니다.

int a = 10;
string s = lexical_cast(a);

이것의 좋은 점 중 하나는 다른 캐스트도 지원한다는 것입니다 (예 : 반대 방향으로도 잘 작동합니다).

또한 Boost lexical_cast는 문자열 스트림에 쓰기 만 한 다음 스트림에서 다시 추출하는 것으로 시작했지만 이제 몇 가지 추가 사항이 있습니다. 우선, 꽤 많은 유형에 대한 전문화가 추가되었으므로 많은 공통 유형의 경우 stringstream을 사용하는 것보다 훨씬 빠릅니다. 둘째, 이제 결과를 확인하므로 (예를 들어) 문자열에서 int로 변환하는 경우 문자열에 int로 변환 할 수없는 항목이 포함되어 있으면 예외가 발생할 수 있습니다 (예 : 1234는 성공하지만 123abc가 던질 것입니다).

C ++ 11부터 정수 유형에 대해 오버로드 된 std :: to_string 함수가 있으므로 다음과 같은 코드를 사용할 수 있습니다.

int a = 20;
std::string s = std::to_string(a);
// or: auto s = std::to_string(a);

표준은이를 sprintf (int의 경우 % d와 같이 제공된 개체 유형과 일치하는 변환 지정자 사용)를 사용하여 충분한 크기의 버퍼로 변환 한 다음 std :: string을 생성하는 것과 동일하다고 정의합니다. 그 버퍼의 내용.


<답변5>

Boost가 설치되어있는 경우 (필요한 경우) :

#include 

int num = 4;
std::string str = boost::lexical_cast(num);

<답변6>

stringstream을 사용하는 것이 더 쉬울 것입니다.

#include 

int x = 42;          // The integer
string str;          // The string
ostringstream temp;  // 'temp' as in temporary
temp << x;
str = temp.str();    // str is 'temp' as string

또는 함수를 만드십시오.

#include 

string IntToString(int a)
{
    ostringstream temp;
    temp << a;
    return temp.str();
}

<답변7>

순수한 C ++에서는 내가 아는 바가 아닙니다. 하지만 당신이 언급 한 것의 약간의 수정

string s = string(itoa(a));

작동해야하며 꽤 짧습니다.


<답변8>

Matthieu M이 제안한대로 C ++ 11에서 사용 가능한 std :: to_string을 사용할 수 있습니다.

std::to_string(42);

또는 성능이 중요한 경우 (예 : 많은 변환을 수행하는 경우) {fmt} 라이브러리의 fmt :: format_int를 사용하여 정수를 std :: string으로 변환 할 수 있습니다.

fmt::format_int(42).str();

또는 C 문자열 :

fmt::format_int f(42);
f.c_str();

후자는 동적 메모리 할당을 수행하지 않으며 Boost Karma 벤치 마크에서 std :: to_string보다 10 배 이상 빠릅니다. 자세한 내용은 C ++에서 빠른 정수를 문자열로 변환을 참조하십시오.

둘 다 스레드로부터 안전합니다.

std :: to_string과 달리 fmt :: format_int는 C ++ 11이 필요하지 않으며 모든 C ++ 컴파일러에서 작동합니다.

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


<답변9>

sprintf ()는 형식 변환에 꽤 좋습니다. 그런 다음 1에서했던 것처럼 결과 C 문자열을 C ++ 문자열에 할당 할 수 있습니다.


<답변10>

먼저 다음을 포함합니다.

#include 
#include 

두 번째 방법을 추가합니다.

template 
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

다음과 같은 방법을 사용하십시오.

NumberToString(69);

또는

int x = 69;
string vStr = NumberToString(x) + " Hello word!."

<답변11>

숫자 변환을 위해 stringstream을 사용하는 것은 위험합니다!

http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/를 참조하십시오. 여기서 operator <<는 형식화 된 출력을 삽입합니다.

현재 로케일에 따라 3 자리 이상의 정수를 4 자리 문자열로 변환하여 천 단위 구분 기호를 추가 할 수 있습니다.

예를 들어 int = 1000은 문자열 1.001로 변환 될 수 있습니다. 이로 인해 비교 작업이 전혀 작동하지 않을 수 있습니다.

따라서 std :: to_string 방식을 사용하는 것이 좋습니다. 더 쉽고 기대 한대로 수행합니다.

업데이트 됨 (아래 설명 참조) :

C ++ 17은 고성능 로케일 독립적 대안으로 std :: to_chars를 제공합니다.


<답변12>

C ++ 98의 경우 몇 가지 옵션이 있습니다.

Boost는 C ++ 라이브러리의 일부가 아니지만 많은 유용한 라이브러리 확장을 포함합니다.

lexical_cast 함수 템플릿은 텍스트로 표시 될 때 임의 유형과의 공통 변환을 지원하기위한 편리하고 일관된 양식을 제공합니다. -Boost의 문서

#include "boost/lexical_cast.hpp"
#include 

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast(x);
    return 0;
}

런타임과 관련하여 lexical_cast 작업은 첫 번째 변환에서 약 80 마이크로 초 (내 컴퓨터에서)가 걸리고 중복으로 수행하면 나중에 상당히 빨라집니다.

이 함수는 ANSI-C로 정의되지 않았고 C ++의 일부가 아니지만 일부 컴파일러에서 지원합니다. -cplusplus.com

이는 gcc / g ++가 itoa를 사용하여 코드를 컴파일 할 수 없음을 의미합니다.

#include 

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}

보고 할 런타임이 없습니다. 나는 itoa를 컴파일 할 수있는 Visual Studio가 설치되어 있지 않다.

sprintf는 C 문자열에서 작동하는 C 표준 라이브러리 함수이며 완벽하게 유효한 대안입니다.

printf에서 format이 사용 된 경우 인쇄되는 동일한 텍스트로 문자열을 작성하지만 인쇄되는 대신 내용은 str이 가리키는 버퍼에 C 문자열로 저장됩니다. -cplusplus.com

#include 

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}

stdio.h 헤더가 필요하지 않을 수 있습니다. 런타임과 관련하여 sprintf 작업은 첫 번째 변환에서 약 40 마이크로 초 (내 컴퓨터에서)가 걸리고 중복으로 수행하면 나중에 상당히 빨라집니다.

이것은 정수를 문자열로 변환하는 C ++ 라이브러리의 주요 방법이며 그 반대의 경우도 마찬가지입니다. ostringstream과 같이 스트림의 의도 된 사용을 더욱 제한하는 stringstream과 유사한 자매 함수가 있습니다. ostringstream을 사용하면 코드 독자에게 기본적으로 << 연산자 만 사용할 것임을 알립니다. 이 함수는 정수를 문자열로 변환하는 데 특히 필요한 모든 것입니다. 보다 자세한 토론은이 질문을 참조하십시오.

#include 
#include 

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}

런타임과 관련하여 ostringstream 작업은 내 컴퓨터에서 약 71 마이크로 초가 걸리고 중복으로 수행하면 나중에 상당히 속도가 빨라지지만 이전 기능 만큼은 아닙니다.

물론 다른 옵션이 있으며 이러한 옵션 중 하나를 자신의 함수로 래핑 할 수도 있지만 이것은 인기있는 일부 옵션에 대한 분석적 관점을 제공합니다.


<답변13>

C ++ 17은 고성능 로케일 독립 대안으로 std :: to_chars를 제공합니다.


<답변14>

스트림과 같은 방식으로 즉석에서 문자열을 구성 할 수있는 구문 적 설탕을 추가하는 것은 다소 쉽습니다.

#include 
#include 

struct strmake {
    std::stringstream s;
    template  strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};

이제 strmake ()에 원하는 것을 추가하고 (연산자 << (std :: ostream & ..)가 정의 된 경우) std :: string 대신 사용할 수 있습니다.

예:

#include 

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}

<답변15>

편집 됨. 고정 된 자릿수를 가진 정수를 왼쪽에 '0'으로 채운 char *로 빠르게 변환해야하는 경우 다음은 리틀 엔디안 아키텍처 (모두 x86, x86_64 및 기타)의 예입니다.

두 자리 숫자를 변환하는 경우 :

int32_t s = 0x3030 | (n/10) | (n%10) << 8;

3 자리 숫자를 변환하는 경우 :

int32_t s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;

4 자리 숫자를 변환하는 경우 :

int64_t s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;

그리고 최대 7 자리 숫자입니다. 이 예에서 n은 주어진 정수입니다. 변환 후 문자열 표현은 (char *) & s로 액세스 할 수 있습니다.

std::cout << (char*)&s << std::endl;

참고 : 빅 엔디안 바이트 순서로 필요한 경우 테스트하지는 않았지만 여기에 예가 있습니다. 3 자리 숫자의 경우 int32_t s = 0x00303030 | (n / 100) << 24 | (n / 10 % 10) << 16 | (n % 10) << 8; 4 자리 숫자 (64 비트 아치) : int64_t s = 0x0000000030303030 | (n / 1000) << 56 | (n / 100 % 10) << 48 | (n / 10 % 10) << 40 | (n % 10) << 32; 작동해야한다고 생각합니다.


<답변16>

사용하다:

#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}

<답변17>

나는 사용한다:

int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast(&(ostringstream() << myint))->str();
string myLD_str = static_cast(&(ostringstream() << myLD))->str();

내 Windows 및 Linux g ++ 컴파일러에서 작동합니다.


<답변18>

할 수있는 또 다른 쉬운 방법이 있습니다.

char str[100];
sprintf(str, "%d", 101);
string s = str;

sprintf는 필요한 형식의 문자열에 데이터를 삽입하는 것으로 잘 알려진 것입니다.

세 번째 줄에 표시된대로 char * 배열을 문자열로 변환 할 수 있습니다.


<답변19>

이것은 나를 위해 일했습니다-

내 코드 :

#include 
using namespace std;

int main()
{
    int n = 32;
    string s = to_string(n);
    cout << "string: " + s  << endl;
    return 0;
}

<답변20>

C ++ 11은 숫자 유형에 대해 std :: to_string ()을 도입했습니다.

int n = 123; // Input, signed/unsigned short/int/long/long long/float/double
std::string str = std::to_string(n); // Output, std::string

<답변21>

사용하다:

#include
#include

std::string intToString(int num);

int main()
{
    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;

    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }
    return numAsStr;
}

<답변22>

int i = 255; std :: string s = std :: to_string (i);

C ++에서 to_string ()은 값을 문자 시퀀스로 표현하여 정수 값의 문자열 객체를 만듭니다.


<답변23>

string number_to_string(int x) {

    if (!x)
        return "0";

    string s, s2;
    while(x) {
        s.push_back(x%10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return s;
}

<답변24>

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

int a = 10;
CString strA;
strA.Format("%d", a);

<답변25>

char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs, "%d", timeStart.elapsed()/1000);
sprintf(bufMs, "%d", timeStart.elapsed()%1000);

<답변26>

namespace std
{
    inline string to_string(int _Val)
    {   // Convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}

이제 to_string (5)을 사용할 수 있습니다.


<답변27>

나는 stringstream을 사용하는 것이 매우 쉽다고 생각합니다.

 string toString(int n)
 {
     stringstream ss(n);
     ss << n;
     return ss.str();
 }

 int main()
 {
    int n;
    cin >> n;
    cout << toString(n) << endl;
    return 0;
 }

<답변28>

카운터 유형의 알고리즘을 사용하여 문자열로 변환합니다. 이 기술은 Commodore 64 컴퓨터 프로그래밍에서 얻었습니다. 게임 프로그래밍에도 좋습니다.

  • 정수를 취하고 10의 거듭 제곱으로 가중치가 부여 된 각 숫자를 취합니다. 따라서 정수가 950이라고 가정합니다. 정수가 100,000보다 크거나 같으면 100,000을 빼고 [ "000000"]에서 문자열의 카운터를 증가시킵니다. 100,000 번 위치에 더 이상 숫자가 없을 때까지 계속합니다. 10의 또 다른 거듭 제곱을 떨어 뜨립니다. 정수가 10,000보다 크거나 같으면 10,000을 빼고 [ "000000"] + 1 위치에서 문자열의 카운터를 늘립니다. 위치 10,000에 더 이상 숫자가 없을 때까지 계속하십시오.
  • 10의 또 다른 거듭 제곱 드롭
  • 패턴 반복

950이 너무 작아서 예제로 사용할 수 없다는 것을 알고 있지만 아이디어를 얻으 셨기를 바랍니다.

728x90

댓글