C ++에서 숫자를 문자열로 또는 그 반대로 변환하는 방법


120

이 질문은 매주 요청 되므로이 FAQ 는 많은 사용자에게 도움 이 될 수 있습니다.

  • C ++에서 정수를 문자열로 변환하는 방법

  • C ++에서 문자열을 정수로 변환하는 방법

  • 부동 소수점 숫자를 C ++에서 문자열로 변환하는 방법

  • C ++에서 문자열을 부동 소수점 숫자로 변환하는 방법


이와 같은 변환을 위해 저는 북마크를 가지고 있습니다. converttypes.com
Firzok Nadeem

답변:


129

C ++ 11 업데이트

의로서 C++11표준 문자열 - 투 - 수 전환 및 그 반대의 표준 라이브러리에 내장되어 있습니다. 다음의 모든 기능은 <string>(21.5 항에 따라)에 있습니다.

문자열을 숫자로

float              stof(const string& str, size_t *idx = 0);
double             stod(const string& str, size_t *idx = 0);
long double        stold(const string& str, size_t *idx = 0);
int                stoi(const string& str, size_t *idx = 0, int base = 10);
long               stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long      stoul(const string& str, size_t *idx = 0, int base = 10);
long long          stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

이들 각각은 문자열을 입력으로 받아 숫자로 변환하려고합니다. 예를 들어 숫자 데이터가 없거나 숫자가 유형의 범위를 벗어 났기 때문에 유효한 숫자를 생성 할 수없는 경우 예외가 발생합니다 ( std::invalid_argument또는 std::out_of_range).

변환이 성공하고하면 idx되지 0, idx디코딩에 사용되지 않은 첫 번째 문자의 인덱스를 포함합니다. 이것은 마지막 문자 뒤의 색인 일 수 있습니다.

마지막으로 정수 유형을 사용하면 9보다 큰 숫자의 경우 알파벳이 가정됩니다 ( a=10까지 z=35). 여기에서 부동 소수점 숫자 , 부호있는 정수부호없는 정수에 대해 구문 분석 할 수있는 정확한 형식에 대한 자세한 정보를 찾을 수 있습니다 .

마지막으로 각 함수에는 a std::wstring를 첫 번째 매개 변수로 받아들이는 오버로드도 있습니다 .

숫자를 문자열로

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

이것들은 더 간단하며 적절한 숫자 유형을 전달하고 문자열을 다시 얻습니다. 형식 지정 옵션의 경우 여기에 다른 답변에 설명 된대로 C ++ 03 stringsream 옵션으로 돌아가서 스트림 조작기를 사용해야합니다.

주석에서 언급했듯이 이러한 함수는 최대 정밀도가 아닌 기본 가수 정밀도로 돌아갑니다. 응용 프로그램에 더 많은 정밀도가 필요한 경우 다른 문자열 형식화 절차로 돌아가는 것이 가장 좋습니다.

명명 된 정의 유사한 기능도 있습니다 to_wstring,이은을 반환합니다 std::wstring.


3
std::to_string부동 소수점 유형에 대해 많은 정밀도를 잃습니다. 예를 들어 double f = 23.4323897462387526; std::string f_str = std::to_string(f);23.432390의 문자열을 반환합니다. 이로 인해 이러한 함수를 사용하여 부동 소수점 값을 왕복 할 수 없습니다.
fun4jimmy 2014

@ fun4jimmy 이것은 표준 또는 구현에 따라 부과되는 제한입니까? 답변에 추가합니다. 라운드 트립이 현을 통해 떠 다니는 것은 좋은 생각이 아닙니다.
KillianDS 2014

C ++ 표준은 "말한다 반환 값 : 각 함수 호출에 의해 생성 될 인수의 값의 문자 표현 들고 문자열 객체를 반환 sprintf(buf, fmt, val)하는 형식 지정자로 " "% d 개를 , " "% U를 , "% ld 개를 " , " % lu " , "% lld " , "% llu " , "% f " , "% f " 또는 "% Lf " , 여기서 buf충분한 크기의 내부 문자 버퍼를 지정합니다. "나는 한 번 봐했다 C99의 표준 의 printf를 나는 소수 자릿수의 수에 의존한다는 생각 #define DECIMAL_DIGfloat.h .
fun4jimmy 2014

Bruce Dawson은 그의 블로그 에 부동 소수점 숫자를 왕복하는 데 필요한 정밀도에 대한 몇 가지 좋은 기사를 제공합니다 .
fun4jimmy 2014

2
이러한 모든 함수는 전역 로케일의 영향을 받으므로 라이브러리를 사용하는 경우 특히 스레드를 사용하는 경우 문제가 발생할 수 있습니다. 여기에서 내 질문을 참조하십시오 : stackoverflow.com/questions/31977457/…
Ident

86

C ++ 03에서 숫자를 문자열로 변환하는 방법

  1. 사용하지 마십시오itoa 또는itof그들이 비표준 때문에 휴대하지 않기 때문에 기능.
  2. 문자열 스트림 사용

     #include <sstream>  //include this to use string streams
     #include <string> 
    
    int main()
    {    
        int number = 1234;
    
        std::ostringstream ostr; //output string stream
        ostr << number; //use the string stream just like cout,
        //except the stream prints not to stdout but to a string.
    
        std::string theNumberString = ostr.str(); //the str() function of the stream 
        //returns the string.
    
        //now  theNumberString is "1234"  
    }
    

    문자열 스트림을 사용하여 부동 소수점 숫자를 문자열로 변환하고 원하는대로 문자열 형식을 지정할 수도 있습니다. cout

    std::ostringstream ostr;
    float f = 1.2;
    int i = 3;
    ostr << f << " + " i << " = " << f + i;   
    std::string s = ostr.str();
    //now s is "1.2 + 3 = 4.2" 
    

    당신은 스트림과 같은 조종 사용할 수 있습니다 std::endl, std::hex및 기능 std::setw(), std::setprecision()와 정확히 같은 방식으로 문자열 스트림과 등cout

    std::ostringstream 혼동하지 마십시오std::ostrstream . 후자는 더 이상 사용되지 않습니다.

  3. 부스트 어휘 캐스트를 사용하십시오 . boost에 익숙하지 않은 경우이 lexical_cast와 같은 작은 라이브러리로 시작하는 것이 좋습니다. boost 및 설명서를 다운로드하고 설치하려면 여기로 이동하십시오 . boost가 C ++ 표준에는 없지만 많은 boost 라이브러리가 결국 표준화되고 boost는 최고의 C ++ 라이브러리로 널리 간주됩니다.

    어휘 캐스트는 그 아래에있는 스트림을 사용하므로 기본적으로이 옵션은 이전 옵션과 동일하며 덜 장황합니다.

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       float f = 1.2;
       int i = 42;
       std::string sf = boost::lexical_cast<std::string>(f); //sf is "1.2"
       std::string si = boost::lexical_cast<std::string>(i); //sf is "42"
    }
    

C ++ 03에서 문자열을 숫자로 변환하는 방법

  1. C에서 상속 된 가장 가벼운 옵션은 함수 atoi(정수 (알파벳에서 정수)) 및 atof(부동 소수점 값 (알파벳에서 부동))입니다. 이러한 함수는 C 스타일 문자열을 인수 ( const char *)로 사용하므로 그 사용법 정확히 좋은 C ++ 관행이 아닌 것으로 간주 될 수 있습니다. cplusplus.com은 atoiatof 모두에 대한 이해하기 쉬운 문서를 가지고 있으며 잘못된 입력의 경우 어떻게 작동 하는지를 포함합니다. 그러나 링크에는 표준에 따라 입력 수가 너무 커서 대상 유형에 맞지 않으면 동작이 정의되지 않는다는 오류가 있습니다.

    #include <cstdlib> //the standard C library header
    #include <string>
    int main()
    {
        std::string si = "12";
        std::string sf = "1.2";
        int i = atoi(si.c_str()); //the c_str() function "converts" 
        double f = atof(sf.c_str()); //std::string to const char*
    }
    
  2. 문자열 스트림 (이번에는 입력 문자열 스트림 istringstream)을 사용합니다. 다시 말하지만, istringstream은 cin. 다시 말하지만, 혼동하지 마십시오 istringstream과 함께 istrstream. 후자는 더 이상 사용되지 않습니다.

    #include <sstream>
    #include <string>
    int main()
    {
       std::string inputString = "1234 12.3 44";
       std::istringstream istr(inputString);
       int i1, i2;
       float f;
       istr >> i1 >> f >> i2;
       //i1 is 1234, f is 12.3, i2 is 44  
    }
    
  3. 부스트 어휘 캐스트를 사용하십시오 .

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       std::string sf = "42.2"; 
       std::string si = "42";
       float f = boost::lexical_cast<float>(sf); //f is 42.2
       int i = boost::lexical_cast<int>(si);  //i is 42
    }       
    

    잘못된 입력의 경우 lexical_cast유형의 예외를 발생시킵니다.boost::bad_lexical_cast


4
에 대한 cplusplus 문서 atoi는 훌륭하지 않으며 올바르지 않습니다. 문자열의 숫자 값을에서 표현할 수없는 int경우 동작이 정의되지 않는다는 것을 언급하지 않습니다. 대신 범위를 벗어난 값은 INT_MAX/ 로 고정되어 INT_MINC ++ 03 또는 C89에서 찾을 수 없습니다. 신뢰할 수없는 / 확인되지 않은 입력의 경우 또는 스트림이 지원하지 않는 기반을 처리 할 때 strtol오류 동작을 정의한 이 필요합니다 . atof/에 대한 유사한 주석 strtod.
Steve Jessop 2011 년

2
cplusplus.com은 "atoi"에 대해 잘못되었습니다. 반환 값에 대해서는 "유효한 변환을 수행 할 수 없으면 0 값이 반환됩니다. 정확한 값이 표현 가능한 값의 범위를 벗어나면 INT_MAX 또는 INT_MIN이 반환됩니다."라고 사양에 나와 있지만 결과의 가치를 표현할 수 없으며 행동은 정의되지 않았습니다. " 그리고 "오류에 대한 동작을 제외하고는 (int)strtol(nptr, (char **)NULL, 10). atoi [...] 함수는 변환 된 값을 반환합니다." cplusplus.com은 초보자를위한 믿을 수 없을 정도로 나쁜 정보 소스로 알려져 있습니다.
Johannes Schaub-litb 2011 년

istr >> i1 >> f >> i2;성공 여부를 확인하지 못합니다.
sbi

4
추가하고 싶을 수도 있습니다std::to_string
Pubby

1
@ArmenTsirunyan : 내 끝에서 +10, 내가 본 최고의 답변 중 하나입니다. 답변 해 주셔서 감사합니다.
Abhineet 2011 년

4

17 ++ C에서 새로운 기능은 표준 : 바꿀수표준 : from_chars이 헤더에 도입 charconv .

std :: to_chars는 로케일과 무관하고 할당되지 않으며 던지지 않습니다.

다른 라이브러리 (예 : std :: sprintf)에서 사용하는 형식화 정책의 일부만 제공됩니다.

에서 표준 : 바꿀수 에 대해 동일한 표준 : from_chars .

std :: from_chars가 to_chars로 포맷 된 모든 부동 소수점 값을 정확히 복구 할 수 있다는 보장은 두 함수가 동일한 구현에서 나온 경우에만 제공됩니다.

 // See en.cppreference.com for more information, including format control.
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <charconv>

using Type =  /* Any fundamental type */ ;
std::size_t buffer_size = /* ... */ ;

[[noreturn]] void report_and_exit(int ret, const char *output) noexcept 
{
    std::printf("%s\n", output);
    std::exit(ret);
}
void check(const std::errc &ec) noexcept
{
    if (ec ==  std::errc::value_too_large)
        report_and_exit(1, "Failed");
}
int main() {
    char buffer[buffer_size];        
    Type val_to_be_converted, result_of_converted_back;

    auto result1 = std::to_chars(buffer, buffer + buffer_size,  val_to_be_converted);
    check(result1.ec);
    *result1.ptr = '\0';

    auto result2 = std::from_chars(buffer, result1.ptr, result_of_converted_back);
    check(result2.ec);

    assert(val_to_be_converted == result_of_converted_back);
    report_and_exit(0, buffer);
}

컴파일러에 의해 완전히 구현되지는 않았지만 확실히 구현 될 것입니다.


0

스트리밍 가능한 모든 것을 문자열로 변환하기 위해 StackOverflow 어딘가에서이 편리한 클래스를 훔쳤습니다.

// make_string
class make_string {
public:
  template <typename T>
  make_string& operator<<( T const & val ) {
    buffer_ << val;
    return *this;
  }
  operator std::string() const {
    return buffer_.str();
  }
private:
  std::ostringstream buffer_;
};

그리고 그것을 다음과 같이 사용합니다.

string str = make_string() << 6 << 8 << "hello";

꽤 멋지다!

또한이 함수를 사용하여 문자열을 스트리밍 가능한 것으로 변환합니다.하지만 숫자가 포함되지 않은 문자열을 구문 분석하려고하면 안전하지 않습니다. (그리고 마지막 것만 큼 영리하지도 않습니다)

// parse_string
template <typename RETURN_TYPE, typename STRING_TYPE>
RETURN_TYPE parse_string(const STRING_TYPE& str) {
  std::stringstream buf;
  buf << str;
  RETURN_TYPE val;
  buf >> val;
  return val;
}

로 사용:

int x = parse_string<int>("78");

wstring에 대한 버전을 원할 수도 있습니다.


5
이것이 바로 boost :: lexical_cast가하는 일입니다. 그리고 부스트는 더 일반적인 fasion에서 그것을합니다.
Armen Tsirunyan 2011 년

사실, 나는 첫 번째 답변을 훑어 보았지만 boost :: lexical_casts를 보지 못했습니다.
Viktor Sehr 2011 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.