Std :: string'i int üçün necə çevirmək olar?

Tez bir sual verin. İnternette bir az baxdım və bir neçə həll tapdım, amma heç biri hələ işləməmişdi. Bir simli bir int üçün konvertasiya baxaraq, mən ASCII kodları demək deyil.

Sürətli bir iş üçün, tənliyi bir simli olaraq keçirik. Onu pozmaq, düzgün biçimləndirmək və doğrusal tənliklər həll etmək lazımdır. İndi bunu söyləyərək, bir daşı intaya çevirə bilmirəm.

Mən bilirəm ki, simli (-5) və ya (25), və s. Formatda olacaq, buna görə də bu, mütləq int. Amma biz bunu simdan çıxarırıq?

Mən düşündüyüm yollardan biri xəttin ardınca / loopu idarə etməkdən, nömrəni yoxlamaqdan sonra bütün nömrələri çıxarmaqdan sonra aparıcı "-" olub-olmadığını görməkdir, əgər varsa, int -1-ə çarpın.

Belə kiçik bir problem üçün bir az mürəkkəb görünür. Hər hansı bir fikir?

367
05 окт. Brandon tərəfindən 05 oct. 2011-10-05 18:23 '11 'da 18:23' də 2011-10-05 18:23
@ 13 cavab

C ++ 11-də std::string növün tipinə qədər yeni yaxşı dönüşüm funksiyaları mövcuddur.

Bunun əvəzinə

 atoi( str.c_str() ) 

istifadə edə bilərsiniz

 std::stoi( str ) 

std::string kimi str sayıdır.

Nömrələrin bütün tatlarında bir versiya var: long stol(string) , float stof(string) , double stod(string) , ... bax http://en.cppreference.com/w/cpp/string/basic_string/stol

562
05 окт. cavab 05 oktyabr cümə axşamı verilir . 2011-10-05 18:59 '11 'da 18:59' da 2011-10-05 18:59
 std::istringstream ss(thestring); ss >> thevalue; 
border=0

Tamamilə doğru olmaq üçün, səhv bayraqları yoxlamaq istəyə bilərsiniz.

55
05 окт. Cavab Winston Ewert 05 oktyabr verilir. 2011-10-05 18:26 '11 at 18:26 2011-10-05 18:26

simli bir tamsayıya çevirmək üçün atoi funksiyasından istifadə edin:

 string a = "25"; int b = atoi(a.c_str()); 

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

35
05 окт. Cavab 05 oktyabr tarixində verilir . 2011-10-05 18:26 '11 at 18:26 2011-10-05 18:26

Mümkün variantlar aşağıda təsvir olunur:

1. İlk seçim: sscanf ()

  #include <cstdio> #include <string> int i; float f; double d; std::string str; // string -> integer if(sscanf(str.c_str(), "%d",  != 1) // error management // string -> float if(sscanf(str.c_str(), "%f",  != 1) // error management // string -> double if(sscanf(str.c_str(), "%lf",  != 1) // error management 

Bu, səhvdir (həmçinin cckcheck tərəfindən göstərilir), çünki "sahə genişliyi məhdudiyyətsiz scanf libc bəzi versiyalarında böyük giriş ilə qəza ola bilər" ( buradaburada bax).

2. İkinci seçim: std :: sto * ()

  #include <iostream> #include <string> int i; float f; double d; std::string str; try { // string -> integer int i = std::stoi(s); // string -> float float f = std::stof(s); // string -> double double d = std::stod(s); } catch (...) { // error management } 

Bu həll qısa və zərifdir, lakin yalnız C ++ 11 uyğun kompilyatorlarda mövcuddur.

3. Üçüncü seçim: sstreams

  #include <string> #include <sstream> int i; float f; double d; std::string str; // string -> integer std::istringstream ( str ) >> i; // string -> float std::istringstream ( str ) >> f; // string -> double std::istringstream ( str ) >> d; // error management ?? 

Lakin, bu həll ilə, pis giriş ayırmaq çətindir (baxın).

4. Dördüncü seçim: Boost lexical_cast

  #include <boost/lexical_cast.hpp> #include <string> std::string str; try { int i = boost::lexical_cast<int>( str.c_str()); float f = boost::lexical_cast<int>( str.c_str()); double d = boost::lexical_cast<int>( str.c_str()); } catch( boost::bad_lexical_cast const ) { // Error management } 

Ancaq, bu, yalnız cənub qövsüdür və sənədlər daha yaxşı səhv idarə edilməsi üçün sstrem-ni ( burada bax) istifadə etməyi təklif edir.

5. Beşinci seçim: strto * ()

Bu həll səhv idarə olunması səbəbindən çox uzun və burada təsvir olunur. Heç bir funksiya sadə bir int qaytarılmasından sonra bir tamsayı halında konvertasiya tələb olunur (baxın, bu necə əldə edilə bilər).

6. Altıncı seçim: Qt

  #include <QString> #include <string> bool ok; std::string; int i = QString::fromStdString(str).toInt( if (!ok) // Error management float f = QString::fromStdString(str).toFloat( if (!ok) // Error management double d = QString::fromStdString(str).toDouble( if (!ok) // Error management 

Nəticələr

Xülasə, ən yaxşı həll C + + 11 std :: stoi () və ya Qt kitabxanalarını istifadə edərək, ikinci seçimdir. Bütün digər qərarlar cəlbedici və ya səhvdir.

27
23 окт. 23 oktyabrda Claudio tərəfindən verilmiş cavab 2014-10-23 17:20 '14 saat 17:20 'da 2014-10-23 17:20

Necə Boost.Lexical_cast haqqında?

Onların nümunəsi bunlardır:

Aşağıdakı nümunə komanda satırının argümanlarını nümerik məlumatların ardıcıllığı kimi qiymətləndirir:

 int main(int argc, char * argv[]) { using boost::lexical_cast; using boost::bad_lexical_cast; std::vector<short> args; while(*++argv) { try { args.push_back(lexical_cast<short>(*argv)); } catch(bad_lexical_cast  { args.push_back(0); } } ... } 
9
05 окт. Cavab verilir Rob 05 oktyabr. 2011-10-05 18:42 '11 saat 06:42 'da 2011-10-05 18:42

Şübhəsiz ki, mənim həllim mənfi ədədlər üçün işləməyəcək, lakin bütün tam ədədləri tam tərkibi olan giriş mətnindən çıxaracaq. numeric_only istifadə edir:

 int main() { int num; std::cin.imbue(std::locale(std::locale(), new numeric_only())); while ( std::cin >> num) std::cout << num << std::endl; return 0; } 

Giriş mətni:

  the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878 

Çıxış tamsayıları:

  5 25 7987 78 9878 

numeric_only sinfi numeric_only kimi müəyyən edilir:

 struct numeric_only: std::ctype<char> { numeric_only(): std::ctype<char>(get_table()) {} static std::ctype_base::mask const* get_table() { static std::vector<std::ctype_base::mask> rc(std::ctype<char>::table_size,std::ctype_base::space); std::fill(  std::ctype_base::digit); return  } }; 

Tam onlayn demo: http://ideone.com/dRWSj

5
05 окт. Cavab 05 oktyabr tarixində verilir . 2011-10-05 18:36 '11 saat 18:36 'də 2011-10-05 18:36

Bu, ehtimal ki, bir az boost::lexical_cast<int>( theString ) , amma boost::lexical_cast<int>( theString ) çox yaxşı işləməlidir.

4
05 окт. James Kanze tərəfindən verilmiş cavab oktyabr 05 2011-10-05 18:43 '11 'də 18:43' də 2011-10-05 18:43

Windows-da istifadə edə bilərsiniz:

 const std::wstring hex = L"0x13"; const std::wstring dec = L"19"; int ret; if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX,  { std::cout << ret << "\n"; } if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX,  { std::cout << ret << "\n"; } 

stringstream , stringstream , stringstream şərh etmək lazımdır, əgər əsas müəyyən etməlisiniz.

1
25 дек. Cavab Jichao 25 dekabr verilir. 2014-12-25 15:44 '14 saat 15:44 2014-12-25 15:44

atoi , simli bir tamsayı təmsil ilə başlayan fərziyyəni bir tamsayıya çevirən daxili funksiyadır.

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

1
05 окт. Cavab Eric tərəfindən 05 oktyabrda verilir . 2011-10-05 18:27 '11 at 18:27 2011-10-05 18:27

Yaxşı, bir çox cavab, bir çox imkanlar. Burada mənə bir simli müxtəlif C ++ tamsayı növlərinə (qısa, int, uzun, bool, ...) çevirən universal bir üsul yoxdur. Aşağıdakı həlli ilə gəldim:

 #include<sstream> #include<exception> #include<string> #include<type_traits> using namespace std; template<typename T> T toIntegralType(const string  { static_assert(is_integral<T>::value, "Integral type required."); T ret; stringstream ss(str); ss >> ret; if ( to_string(ret) != str) throw invalid_argument("Can't convert " + str); return ret; } 

Burada istifadə nümunələri:

 string str = "123"; int x = toIntegralType<int>(str); // x = 123 str = "123a"; x = toIntegralType<int>(str); // throws exception, because "123a" is not int str = "1"; bool y = toIntegralType<bool>(str); // y is true str = "0"; y = toIntegralType<bool>(str); // y is false str = "00"; y = toIntegralType<bool>(str); // throws exception 

Nə stringstream çıxış operatorunu simli bir tamsayı tipinə çevirmək üçün istifadə etmirsiniz? İşdə cavab: simli tam ədəd üçün məhdudiyyəti aşan bir dəyər ehtiva edir. Məsələn, Wndows 64 max int 2147483647'e bərabərdir. Diyelim ki, max int + 1: string str = "2147483648" bir dize dəyəri təyin edək. İndi int üçün bir simli çevirərkən:

 stringstream ss(str); int x; ss >> x; 

x 2147483647 olur, bu da bir səhvdir: "2147483648" simli int 2147483647 ünvanına çevrilməməlidir. İntegralType verilən funksiya belə səhvləri algılar və bir istisna atır.

0
06 дек. Cavab verilir Andrushenko Alexander 06 dek. 2018-12-06 18:13 '18 də 18:13 2018-12-06 18:13 'də

long n = strtol(s.c_str(), NULL, base); versiya: long n = strtol(s.c_str(), NULL, base); ,

( s bir simli və base 2, 8, 10, 16 kimi int ).

strtol haqqında daha ətraflı məlumat üçün bu linkə müraciət edə bilərsiniz.


Əsas fikir strtol də daxil edilən strtol funksiyasından istifadə cstdlib .

strtol bir sıra strtol olduğundan string bir araya çevirməliyik. Bu linkə istinad edə bilərsiniz.

Məsələn:

 #include <iostream> #include <string> // string type #include <bitset> // bitset type used in the output int main(){ s = "1111000001011010"; long t = strtol(s.c_str(), NULL, 2); // 2 is the base which parse the string cout << s << endl; cout << t << endl; cout << hex << t << endl; cout << bitset<16> (t) << endl; return 0; } 

çıxacaq olan:

 1111000001011010 61530 f05a 1111000001011010 
0
24 янв. Cavab Hansimov 24 yanvar verilir 2019-01-24 11:16 '19 'da 11:16' da

Mən istifadə edərkən bu gözəl işləyir:

 int myint = int::Parse(mystring); 
-2
01 окт. Joe 01 oktyabr göndərdi 2013-10-01 12:44 '13 at 12:44 2013-10-01 12:44

başqa bir sadə yol var: c='4' tipli bir xarakterə malik olduğunuzu güman et ki, aşağıdakı addımlardan birini edə bilərsiniz:

1-ci int q

q=(int) c ; (q is now 52 in ascii table ) . q=q-48; remember that adding 48 to digits is their ascii code .

İkinci yol:

q=c-'0'; the same , character '0' means 48

-2
30 дек. Cavab noob 30 dek ilə verilir. 2013-12-30 13:56 '14 'da 13:56' de 2013-12-30 13:56

Tags ilə bağlı digər suallar və ya bir sual