Programowanie w języku C/C++

Konwersje int na string i string na int

Wiele osób pyta się jak przekonwertować w C/C++ int na string i odwrotnie; na naszym forum takie wątki pojawiają się średnio co dwa tygodnie a ich autorzy tłumaczą się nieraz, że "nie znaleźli w Google". Postanowiłem wyjść temu na przeciw i przedstawić sposoby wykonania tegoż mając nadzieję, że tekst zostanie dobrze wypozycjonowany w wyszukiwarkach.

Spis treści

     1 int na string
          1.1 [C++] ostringstream
          1.2 [C/C++] itoa
          1.3 [C/C++] sprintf
          1.4 Własna funkcja
          1.5 Standard C++11
          1.6 Biblioteka Boost
     2 string na int
          2.1 [C++] istringstream
          2.2 [C/C++] atoi
          2.3 [C/C++] sscanf
          2.4 [C/C++] strtol
          2.5 Standard C++11
          2.6 Własna funkcja
          2.7 Biblioteka Boost

int na string


[C++] ostringstream


Nagłówek: sstream

Klasa string
int i = 42;
ostringstream ss;
ss << i;
string str = ss.str();


[C/C++] itoa


Nagłówek: cstdlib (C++), stdlib.h (C)

Uwaga! Funkcja ta nie istnieje w standardzie ANSI-C, nie ma jej też w C++. Aczkolwiek są kompilatory, które ją posiadają. Zamiast itoa zaleca się używanie sprintf.

Klasa string (C++)
int i = 42;
string tmp; // brzydkie rozwiązanie
itoa(i, (char*)tmp.c_str(), 10);
string str = tmp.c_str();


char* (C/C++)
int i = 42;
char *str;
itoa(i, str, 10);


[C/C++] sprintf


Nagłówek: cstdio (C++), stdio.h (C)

Klasa string (C++)
int i = 42;
string tmp; // brzydkie rozwiązanie
sprintf((char*)tmp.c_str(), "%d", i);
string str = tmp.c_str();


char* (C/C++)
int i = 42;
char *str;
sprintf(str, "%d", i);


Własna funkcja


Można jeszcze napisać własną funkcję - tylko po co? Dla dociekliwych pokażę jak mogłaby taka prosta implementacja wyglądać.

Zwracająca obiekt klasy string (C++)
string intToStr(int n)
{
     string tmp, ret;
     if(n < 0) {
      ret = "-";
      n = -n;
     }
     do {
      tmp += n % 10 + 48;
      n -= n % 10;
     }
     while(n /= 10);
     for(int i = tmp.size()-1; i >= 0; i--)
      ret += tmp[i];
     return ret;
}


Zwracająca obiekt klasy string (C++), wersja rekurencyjna
string intToStr(int n)
{
     string tmp;
     if(n < 0) {
      tmp = "-";
      n = -n;
     }
     if(n > 9)
      tmp += intToStr(n / 10);
     tmp += n % 10 + 48;
     return tmp;
}


Zwracająca char* (C/C++)
char* intToStr(int n)
{
     int i = 0;
     char tmp[12];
     static char ret[12];
     if(n < 0) {
      *ret = '-';
      i++;
      n = -n;
     }
     do {
      *tmp = n % 10 + 48;
      n -= n % 10;
      if(n > 9) *tmp++;
     }
     while(n /= 10);
     while(ret[i++] = *tmp--);
     return ret;
}

Standard C++11


Do konwersji liczby na string'a można by też użyć std::to_string z C++11.
Uwaga: Jeżeli kompilator nie zna tej funkcji należy go zaktualizować!

Oto kilka przykładów z użyciem funkcji std::to_string.
int do string
#include <iostream>
#include <string>
int main() 
{
    // konwersja int do string'a
    int value = 23;
    std::string _str = std::to_string(value);
 
    std::cout << _str << "\n";
}
double do string
#include <iostream>
#include <string>
int main() 
{
    // konwersja double do string'a
    double value = 23.43;
    std::string _str = std::to_string(value);
 
    std::cout << _str << "\n";
}
float do string
#include <iostream>
#include <string>
int main() 
{
    // konwersja float do string'a
    float value = 23.4;
    std::string _str = std::to_string(value);
 
    std::cout << _str << "\n";
}
long do string
#include <iostream>
#include <string>
int main() 
{
    // konwersja long do string'a
    long value = 23;
    std::string _str = std::to_string(value);
 
    std::cout << _str << "\n";
}


Biblioteka Boost


Jeśli mamy dostęp do popularnej biblioteki Boost, możemy do konwersji wykorzystać klasę lexical_cast:

#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
 
int main()
{
    int value = 42;
    std::string str = boost::lexical_cast<std::string>(value);
 
    std::cout << str << std::endl;
    return 0;
}


string na int


[C++] istringstream


Nagłówek: sstream

string str = "123";
int i;
istringstream iss(str);
iss >> i;


[C/C++] atoi


Nagłówek: cstdlib (C++), stdlib.h (C)

Klasa string (C++)
string str = "123";
int i = atoi(str.c_str());


char* (C/C++)
char *str = "123";
int i = atoi(str);

Istnieje jeszcze podobna funkcja atol różniąca się od atoi tym, że konwertuje na typ long int (albo atof na double - liczby zmiennoprzecinkowe).

[C/C++] sscanf


Nagłówek: cstdio (C++), stdio.h (C)

Klasa string (C++)
string str = "123";
int i;
sscanf(str.c_str(), "%d", &i);


char* (C/C++)
char *str = "123";
int i;
sscanf(str, "%d", &i);


[C/C++] strtol


Nagłówek: cstdlib (C++), stdlib.h (C)

Klasa string (C++)
string str = "123";
int i = strtol(str.c_str(), NULL, 10);


char* (C/C++)
char *str = "123";
int i = strtol(str, NULL, 10);


Standard C++11


String na double.
double stod (const string&  str, size_t* idx = 0);
double stod (const wstring& str, size_t* idx = 0);

str - String reprezentujący liczbę zmiennoprzecinkową.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
#include <iostream>   // std::cout
#include <string>     // std::string, std::stod
 
int main (){
    std::string orbits ("365.24 29.53");
    std::string::size_type sz;     // alias of size_t
 
    double earth = std::stod (orbits,&sz);
    double moon = std::stod (orbits.substr(sz));
    std::cout << "The moon completes " << (earth/moon) << " orbits per Earth year.\n";
    return 0;
}

String na float.
float stof (const string&  str, size_t* idx = 0);
float stof (const wstring& str, size_t* idx = 0);

str - String reprezentujący liczbę zmiennoprzecinkową.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
#include <iostream>   // std::cout
#include <string>     // std::string, std::stof
 
int main (){
    std::string orbits ("686.97 365.24");
    std::string::size_type sz;     // alias of size_t
 
    float mars = std::stof (orbits,&sz);
    float earth = std::stof (orbits.substr(sz));
    std::cout << "One martian year takes " << (mars/earth) << " Earth years.\n";
    return 0;
}

String na int.
int stoi (const string&  str, size_t* idx = 0, int base = 10);
int stoi (const wstring& str, size_t* idx = 0, int base = 10);

str - String reprezentujący liczbę.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
base - System, w jakim liczba ma być interpretowana; Domyślnie dziesiątkowy.
#include <iostream>   // std::cout
#include <string>     // std::string, std::stoi
 
int main (){
    std::string str_dec = "2001, A Space Odyssey";
    std::string str_hex = "40c3";
    std::string str_bin = "-10010110001";
    std::string str_auto = "0x7f";
 
    std::string::size_type sz;   // alias of size_t
 
    int i_dec = std::stoi (str_dec,&sz);
    int i_hex = std::stoi (str_hex,nullptr,16);
    int i_bin = std::stoi (str_bin,nullptr,2);
    int i_auto = std::stoi (str_auto,nullptr,0);
 
    std::cout << str_dec << ": " << i_dec << " and [" << str_dec.substr(sz) << "]\n";
    std::cout << str_hex << ": " << i_hex << '\n';
    std::cout << str_bin << ": " << i_bin << '\n';
    std::cout << str_auto << ": " << i_auto << '\n';
 
  return 0;
}

String na long.
long stol (const string&  str, size_t* idx = 0, int base = 10);
long stol (const wstring& str, size_t* idx = 0, int base = 10);

str - String reprezentujący liczbę.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
base - System, w jakim liczba ma być interpretowana; Domyślnie dziesiątkowy.
#include <iostream>   // std::cout
#include <string>     // std::string, std::stol
 
int main (){
    std::string str_dec = "1987520";
    std::string str_hex = "2f04e009";
    std::string str_bin = "-11101001100100111010";
    std::string str_auto = "0x7fffff";
 
    std::string::size_type sz;   // alias of size_t
 
    long li_dec = std::stol (str_dec,&sz);
    long li_hex = std::stol (str_hex,nullptr,16);
    long li_bin = std::stol (str_bin,nullptr,2);
    long li_auto = std::stol (str_auto,nullptr,0);
 
    std::cout << str_dec << ": " << li_dec << '\n';
    std::cout << str_hex << ": " << li_hex << '\n';
    std::cout << str_bin << ": " << li_bin << '\n';
    std::cout << str_auto << ": " << li_auto << '\n';
 
    return 0;
}

String na long double.
long double stold (const string&  str, size_t* idx = 0);
long double stold (const wstring& str, size_t* idx = 0);

str - String reprezentujący liczbę zmiennoprzecinkową.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
#include <iostream>   // std::cout
#include <string>     // std::string, std::stod
 
int main (){
    std::string orbits ("90613.305 365.24");
    std::string::size_type sz;     // alias of size_t  
 
    long double pluto = std::stod (orbits,&sz);
    long double earth = std::stod (orbits.substr(sz));
    std::cout << "Pluto takes " << (pluto/earth) << " years to complete an orbit.\n";
    return 0;
}

String na long long.
long long stoll (const string&  str, size_t* idx = 0, int base = 10);
long long stoll (const wstring& str, size_t* idx = 0, int base = 10);

str - String reprezentujący liczbę.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
base - System, w jakim liczba ma być interpretowana; Domyślnie dziesiątkowy.
#include <iostream>   // std::cout
#include <string>     // std::string, std::stoll
 
int main (){
    std::string str = "8246821 0xffff 020";
 
    std::string::size_type sz = 0;   // alias of size_t
 
    while (!str.empty()) {
        long long ll = std::stoll (str,&sz,0);
        std::cout << str.substr(0,sz) << " interpreted as " << ll << '\n';
        str = str.substr(sz);
    }
 
    return 0;
}

String na unsigned long.
unsigned long stoul (const string&  str, size_t* idx = 0, int base = 10);
unsigned long stoul (const wstring& str, size_t* idx = 0, int base = 10);

str - String reprezentujący liczbę.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
base - System, w jakim liczba ma być interpretowana; Domyślnie dziesiątkowy.
#include <iostream>   // std::cin, std::cout
#include <string>     // std::string, std::stoul, std::getline
 
int main (){
    std::string str;
    std::cout << "Enter an unsigned number: ";
    std::getline (std::cin,str);
    unsigned long ul = std::stoul (str,nullptr,0);
    std::cout << "You entered: " << ul << '\n';
    return 0;
}

String na unsigned long long.
unsigned long long stoull (const string&  str, size_t* idx = 0, int base = 10);
unsigned long long stoull (const wstring& str, size_t* idx = 0, int base = 10);

str - String reprezentujący liczbę.
idx - Wskaźnik ustawiany na pozycję pierwszego znaku w stringu po liczbie.
base - System, w jakim liczba ma być interpretowana; Domyślnie dziesiątkowy.
// stoull example
#include <iostream>   // std::cout
#include <string>     // std::string, std::stoull
 
int main (){
    std::string str = "8246821 0xffff 020 -1";
 
    std::string::size_type sz = 0;   // alias of size_t
 
    while (!str.empty()) {
        unsigned long long ull = std::stoull (str,&sz,0);
        std::cout << str.substr(0,sz) << " interpreted as " << ull << '\n';
        str = str.substr(sz);
    }
 
    return 0;
}


Własna funkcja


A tak mogłyby wyglądać proste implementacje funkcji:

Przyjmująca jako argument obiekt klasy string (C++)
int strToInt(string s)
{
    bool m=false;
    int tmp=0;
    int i=0;
    if(s[0]=='-')
    {
          i++;
          m = true;
    }
    while(i<s.size())
    {
      tmp = 10*tmp+s[i]-48;
      i++;
    }
    return m ? -tmp : tmp;   
}


Przyjmująca jako argument char* (C/C++)
int strToInt(char *s)
{
     int tmp = 0, m = 0;
     if(*s == '-') {
      m = 1;
      *s++;
     }
     while(*s)
      tmp = 10 * tmp + *s++ - 48;
     return m ? -tmp : tmp;
}


Biblioteka Boost


Jeśli mamy dostęp do biblioteki Boost, możemy do konwersji wykorzystać klasę lexical_cast:

#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
 
int main()
{
    std::string str = "42";
    int value = boost::lexical_cast<int>(str);
 
    std::cout << value << std::endl;
    return 0;
}



Zobacz też:

10 komentarzy

MarcinDj 2015-04-09 12:42

Z Delphi przerzucam się na c++, ale tu serce mnie boli... 10 różnego rodzaju konwersji, z czego każda wymaga kilku linijek kodu, jakby programista nie miał co robić. Pewnie, niech sam funkcje napisze...
w Delphi jest strtoint(), inttostr() i tyle....

fornakter 2015-01-03 21:58

Dlaczego int i = atoi(str.c_str()); nie przerabia mi liter na jakąś wartość, tylko na 0? A liczby zapisane w string zamienia na tą samą, z tego co się orientuję to (str=1)!=(int=1), czy może się mylę...?

Googler 2014-12-01 11:29

Wielkie dzięki :) Akurat tego szukałem ;)

Brak avatara
janusz 2014-04-26 20:53

Chciałbym nauczyć się czaru, dzięki któremu mógłbym zmieniać formę. Jak zgadnąć słowa inkantacji?

Adam Boduch 2014-03-04 14:40

To jest wiki, możesz poprawić sam klikając przycisk "Popraw ten artykuł".

Brak avatara
edpeix 2014-01-14 15:33

Wezcie to poprawcie albo usuńcie bo to itoa(i, (char*)tmp.c_str(), 10); i podobne niżej aż wołają o pomste do nieba !

fortuda 2013-03-08 22:00

Proszę o pomoc...
chodzi mi o konwersję string na long int czyli ze stringu  string str = "123abc"; powinienem otrzymać wynik w postaci liczby dziesiętnej np takiej 15477424852447211265. oczywiście do unsigned long long inta
co ciekawe
1) string 123 przy użyciu atol daje int 123, a powinien np 214235634763
2) string abc daje poprawną wartość czyli coś w rodzaju 154366278856
3)string 123abc daje poprzez atol lub inna 123

moge zrobic to w postaci zmiany string na binarną potem binarna 64 na long int
ale szukam bezpośredniej metody. prosze o pomoc...

Nerin 2011-12-13 10:00

Wiele razy używałem tego tematu do przypomnienia sobie konwersji. Autor omówił wiele sposobów konwersji, a pierwszy komentarz jest komentarzem niedoszłego programisty.

ayufanpl 2008-06-19 19:22

Sporo błędów jest w tym arcie... i ogólnie to nie ma prawa dobrze działać. W paru miejscach jest nieoptymalne użycie konstrukcji.

Zacznijmy

1)
int i = 42;
string tmp; // brzydkie rozwiązanie
itoa(i, (char*)tmp.c_str(), 10);
string str = tmp.c_str();

string jest domyślnie pusty... to jest użycie niezgodne z standardem. TAKA KONSTRUKCJA NIE POWINNA BYĆ UŻYWANA!!!

2) int i = 42;
char *str;
itoa(i, str, 10);

str wskazuje na nieznany obszar pamięci... jeśli ktoś chce tego poprawnie użyć powinien napisać:
char str[15];
itoa(i, str, 10);

3) Podobnie jest z odpowiednikami sprintfowymi...

4) Zapis: lepsze jest użycie takiej konstrukcji: int strToInt(const string &s) (jeśli ktoś nie wie dlaczego akurat tak polecam przeczytanie Megatutorialu albo porządnej książki do C++)

5) Zapis: bardzo podobnie: int strToInt(const char *s)

Reasumując osoba, która to pisała ma bardzo małe pojęcie o programowaniu w C/C++... szok i przerażenie...

KT

tomek107 2007-12-19 16:15

Wielkie dzięki!!!
Właśnie potrzebna było mi taka konwersja do programu. Nie musiałem szukać i od razu tyle wersji (przy czym strtol najszybszy na string->int) :)
Prosto i na temat. Super!