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
     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 Własna funkcja

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 = (char*)malloc(12); // stdlib
     char *ret = (char*)malloc(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;
}


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);


Własna funkcja

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

Przyjmująca jako argument obiekt klasy string (C++)
int strToInt(string s)
{
     int tmp = 0, i = 0;
     bool m = false;
     if(s[0] == '-') {
          m = true;
          i++;
     }
     for(; i < s.size(); i++)
          tmp = 10 * tmp + s[i] - 48;
     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;
}


Zobacz też:

Kategoria: C/C++

3 komentarze

Brak avatara
Napisany 2011-12-13 10:00 przez Nerin

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.

Brak avatara
Napisany 2008-06-19 19:22 przez ayufanpl

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

Brak avatara
Napisany 2007-12-19 16:15 przez tomek107

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!

4programmers.net