2010-12-14 6 views
54

가능한 중복 :
How to parse a string to an int in C++?C++ 구문 분석 INT

내가 어떤 연구를하고 어떤 사람들은 페이지에 계속를 사용하여 말하고 다른 사람들이 나쁜 말을, 내가 얻을 수 없다 그것은 어쨌든 작동합니다.

그래서 난 그냥 올바른 방법은 INT 문자열을 변환 뭐죠, 평면 밖으로 물어보고 싶은.

string s = "10"; 
int i = s....? 

고마워요!

+3

아마도 (std ::')'string s = "10"'을 의미했을 것입니다. – lijie

+1

중복 된 http://stackoverflow.com/questions/200090/how-do-you-convert-ac-string-to-an-int 및 http://stackoverflow.com/questions/194465/how-to-parse -a-string-to-an-int-in-c –

+0

@lijie - 어쩌면 내 코드에서 그렇게 말할 필요는 없다 ...? – kralco626

답변

64
  • C++ 11에 사용 std::stoi로서 :

    std::string s = "10"; 
    int i = std::stoi(s); 
    

    std::stoi이 변환을 수행 할 수 없을 경우, 형식 std::invalid_argument의 예외를 발생 또는 플로우의 변환 결과 경우 std::out_of_range 않습니다 (즉 문자열 값이 int 유형에 비해 너무 큰 경우). 당신이 경우 int 입력 문자열이 너무 작은 것 같습니다에 불구하고 std::stol 또는 std:stoll를 사용할 수 있습니다. 에서

  • C++ 다음 중 하나를 사용할 수 있습니다/98 03 : 위의 두 가지 방법이 입력 s = "10jh" 실패 할 것이라고

    std::string s = "10"; 
    int i; 
    
    //approach one 
    std::istringstream(s) >> i; //i is 10 after this 
    
    //approach two 
    sscanf(s.c_str(), "%d", &i); //i is 10 after this 
    

참고. 그들은 오류를 알리는 대신 10을 반환합니다. 따라서 안전하고 강력한 접근 방법은 입력 문자열을 구문 분석하고 각 문자가 숫자인지 확인한 다음 그에 따라 작업하는 자체 함수를 작성하는 것입니다. my another solution

int to_int(char const *s) 
{ 
    if (s == NULL || *s == '\0') 
     throw std::invalid_argument("null or empty string argument"); 

    bool negate = (s[0] == '-'); 
     if (*s == '+' || *s == '-')  
        ++s; 

    if (*s == '\0') 
     throw std::invalid_argument("sign character only."); 

     int result = 0; 
     while(*s) 
     { 
          if (*s >= '0' && *s <= '9') 
          { 
              result = result * 10  - (*s - '0');  //assume negative number 
          } 
          else 
              throw std::invalid_argument("invalid input string"); 
          ++s; 
     } 
     return negate ? result : -result; //-result is positive! 
}  

이 용액을 약간 수정 된 버전 : 여기에서 강력한 implemtation (비록 안된)이다.

+4

일반적으로 사용자 제공 입력에서'atoi'를 피할 것입니다. 0을 얻었을 때, 문자열에''0 ''이 있거나 유효하지 않기 때문에. –

+0

Atoi와 itoa는 종종 문제를 일으킬 수 있으므로 이러한 기능을 피하는 것이 좋습니다. 대신 boost 또는 stringstream을 사용합니다. – RageD

+0

단순한 프로젝트이기 때문에 빠른 프로젝트에 좋습니다 – kralco626

7

당신은 istringstream를 사용할 수 있습니다.

string s = "10"; 

// create an input stream with your string. 
istringstream is(str); 

int i; 
// use is like an input stream 
is >> i; 
12

당신은 boost::lexical_cast를 사용할 수 있습니다

#include <iostream> 
#include <boost/lexical_cast.hpp> 

int main(int argc, char* argv[]){ 
std::string s1 = "10"; 
std::string s2 = "abc"; 
int i; 

    try { 
     i = boost::lexical_cast<int>(s1); 
    } 
    catch(boost::bad_lexical_cast & e){ 
     std::cout << "Exception caught : " << e.what() << std::endl; 
    } 

    try { 
     i = boost::lexical_cast<int>(s2); 
    } 
    catch(boost::bad_lexical_cast & e){ 
     std::cout << "Exception caught : " << e.what() << std::endl; 
    } 

    return 0; 
} 
+9

boost lexical_cast is very 아주 아주 천천히. 또한 예외 처리가 필요하다는 사실 때문에 사용하기가 훨씬 더 새삼 스럽습니다. 사용자 속도에서 제공되는 입력에만 좋으며 그 밖의 것은 없습니다. –

+0

@dman : 실제로 lexical_cast는 atoi/strtol/sscanf보다 느리지 만 1) OP는 가장 빠른 방법을 묻지 않았습니다. (질문은 C++로 태그가 붙습니다) 2) lexical_cast는 일반적인 해결책이며 Boost에 포함되어있어 구현의 품질에 대해 3) bad_lexical_cast 예외는 변환 오류, 적절한 오류 처리 비용을 지불하는 작은 가격을 감지 할 수있는 방법을 제공합니다. 4) lexical_cast 병목 현상이 발생하면 데이터 유형의 특수화를 구현하는 것이 매우 쉽습니다. –

+0

+1 . 나는 당신의 주장을 좋아하고 실제로 해결책을 좋아합니다. 자바를 좋아하는 사람이라면 앞으로도이 솔루션을 사용할 가능성이 높습니다. – kralco626

9

에는 "올바른 방법"이 존재하지 않는다. 범용 (그러나 차선책) 솔루션을 원한다면 boost : lexical cast를 사용할 수 있습니다.

C++에 대한 일반적인 해결책은 STD와 :: ostream에 < < 연산자를 사용하는 것이다. 문자열로 변환하려면 stringstream 및 stringstream :: str() 메서드를 사용할 수 있습니다.당신이 정말로 빠른 메커니즘이 필요한 경우

(만약 당신이 http://www.partow.net/programming/strtk/index.html

안부와 같은 "전용"솔루션을
마르신

+19

"길이 없다"- 문자열을 파싱하는 "올바른 방법"이없는 언어를 좋아해야합니다 ...: – kralco626

4

일부 편리한 빠른 기능을 볼 수 있습니다 (20/80 규칙을 기억) 사용하지 않는 부스트) :

template<typename T> 
std::string ToString(const T& v) 
{ 
    std::ostringstream ss; 
    ss << v; 
    return ss.str(); 
} 

template<typename T> 
T FromString(const std::string& str) 
{ 
    std::istringstream ss(str); 
    T ret; 
    ss >> ret; 
    return ret; 
} 

예 :

int i = FromString<int>(s); 
std::string str = ToString(i); 

모든 스트리밍 가능 유형 (부동 소수점 등)에서 작동합니다. #include <sstream> 및 가능하면 #include <string>이 필요합니다.

+2

이것은 boost :: lexical_cast가 사용하는 솔루션입니다. – Marcin

+0

Actualla boost :: lexical_cast는 원래 std 문자열 스트림을 사용하지 않지만 일부 함수는이 함수보다 조금 더 빨리 만들어야합니다. (입력이 추출 연산자에 의해 완전히 소모되었는지 확인하는 것을 포함하여) 검사하기 때문에 두 함수보다 훨씬 안전합니다. –