2010-12-14 4 views
54

可能性の重複:
How to parse a string to an int in C++?C++の構文解析int型

私はいくつかの研究を行っていると、一部の人々はatioを使用するように言うと、他の人はそれが悪いと言うと、私は得ることができませんそれはとにかく働く。

私はちょうどフラットで、文字列を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++ 03/98で

  • 、以下のいずれかを使用することができる:上記の二つのアプローチが入力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! 
}  

このソリューションは、わずかに修正されたバージョン:ここでは1堅牢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はとてもです非常に非常に遅い。また、例外処理が必要であるという事実により、使用するのがより寛容になります。ユーザーのスピードで入力される入力にのみ適しています。 –

+0

@dman:確かにlexical_castはatoi/strtol/sscanfよりも遅いですが、1)OPは最も速い方法について質問しませんでした。(質問はC++とタグ付けされています)2)lexical_castは一般的な解決策であり、Boostの一部です実装の品質について3)bad_lexical_cast例外は、変換エラーを検出する方法、適切なエラー処理のために支払う小さな値段を提供します4)lexical_castがボトルネックの場合、データ型の特殊化を実装するのはかなり簡単です –

+0

+1 。私はあなたの議論が好きで、私は実際にその解決策が好きです。私が好きなJavaの人であることは、将来このソリューションを使用する可能性があります。 – kralco626

9

ない "正しい方法" はありません。普遍的な(しかし最適ではない)ソリューションが必要な場合は、boost :: lexicalキャストを使用できます。

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ストリングストリームを使用しませんが、これらの機能より少し速くすべきいくつかの調整済みストリームクラスを使用します。 (入力が抽出演算子によって完全に消費されたかどうかのチェックを含む)チェックであるので、2つの関数よりもはるかに安全です。 –

関連する問題