Cómo convertir un número a cadena y viceversa en C ++

Dado que esta pregunta se realiza cada semana, estas preguntas frecuentes pueden ayudar a muchos usuarios.

Actualización para C ++ 11

A partir del estándar C++11 , la conversión de cadena a número y viceversa está integrada en la biblioteca estándar. Todas las siguientes funciones están presentes en (según el párrafo 21.5).

cadena a numérico

 float stof(const string& str, size_t *idx = 0); double stod(const string& str, size_t *idx = 0); long double stold(const string& str, size_t *idx = 0); int stoi(const string& str, size_t *idx = 0, int base = 10); long stol(const string& str, size_t *idx = 0, int base = 10); unsigned long stoul(const string& str, size_t *idx = 0, int base = 10); long long stoll(const string& str, size_t *idx = 0, int base = 10); unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10); 

Cada uno de estos toma una cadena como entrada e intentará convertirla en un número. Si no se puede construir un número válido, por ejemplo, porque no hay datos numéricos o el número está fuera del rango para el tipo, se lanza una excepción ( std::invalid_argument o std::out_of_range ).

Si la conversión tuvo éxito e idx no es 0 , idx contendrá el índice del primer carácter que no se utilizó para la deencoding. Esto podría ser un índice detrás del último personaje.

Finalmente, los tipos integrales permiten especificar una base, para dígitos mayores que 9, se asume el alfabeto ( a=10 hasta z=35 ). Puede encontrar más información sobre el formato exacto que se puede analizar aquí para números de coma flotante , enteros con signo y enteros sin signo .

Finalmente, para cada función también hay una sobrecarga que acepta un std::wstring como su primer parámetro.

numérico a cadena

 string to_string(int val); string to_string(unsigned val); string to_string(long val); string to_string(unsigned long val); string to_string(long long val); string to_string(unsigned long long val); string to_string(float val); string to_string(double val); string to_string(long double val); 

Estos son más sencillos, pasas el tipo numérico apropiado y recuperas una cadena. Para las opciones de formato, debe volver a la opción C ++ 03 stringsream y usar los manipuladores de flujo, como se explica en otra respuesta aquí.

Como se señaló en los comentarios, estas funciones se reducen a una precisión de mantisa predeterminada que probablemente no sea la precisión máxima. Si se requiere más precisión para su aplicación, también es mejor volver a otros procedimientos de formato de cadenas.

También hay funciones similares definidas que se denominan to_wstring , estas devolverán std::wstring .

Cómo convertir un número a una cadena en C ++ 03

  1. No use las funciones itoa o itof porque no son estándar y, por lo tanto, no son portátiles.
  2. Usar secuencias de cadenas

      #include  //include this to use string streams #include  int main() { int number = 1234; std::ostringstream ostr; //output string stream ostr < < number; //use the string stream just like cout, //except the stream prints not to stdout but to a string. std::string theNumberString = ostr.str(); //the str() function of the stream //returns the string. //now theNumberString is "1234" } 

    Tenga en cuenta que también puede usar secuencias de cadenas para convertir números de coma flotante en cadenas, y también para formatear la cadena como desee, al igual que con cout

     std::ostringstream ostr; float f = 1.2; int i = 3; ostr < < f << " + " i << " = " << f + i; std::string s = ostr.str(); //now s is "1.2 + 3 = 4.2" 

    Puede usar manipuladores de flujo, tales como std::endl , std::hex y funciones std::setw() , std::setprecision() etc. con secuencias de cadenas exactamente de la misma manera que con cout

    No confunda std::ostringstream con std::ostrstream . Este último está en desuso

  3. Utilice el reparto léxico de impulso . Si no está familiarizado con el impulso, es una buena idea comenzar con una pequeña biblioteca como este lexical_cast. Para descargar e instalar boost y su documentación, vaya aquí . Aunque el impulso no está en el estándar C ++, muchas bibliotecas de boost se estandarizarán eventualmente y el boost es ampliamente considerado como la mejor biblioteca C ++.

    El yeso léxico usa transmisiones debajo, así que básicamente esta opción es la misma que la anterior, apenas menos detallada.

     #include  #include  int main() { float f = 1.2; int i = 42; std::string sf = boost::lexical_cast(f); //sf is "1.2" std::string si = boost::lexical_cast(i); //sf is "42" } 

Cómo convertir una cadena a un número en C ++ 03

  1. La opción más ligera, heredada de C, son las funciones atoi (para enteros (alfabético a entero)) y atof (para valores de coma flotante (alfabético para flotar)). Estas funciones toman una cadena de estilo C como argumento ( const char * ) y, por lo tanto, su uso puede considerarse una práctica de C ++ no exactamente buena. cplusplus.com tiene documentación fácil de entender tanto sobre atoi como sobre cómo se comportan en caso de mala entrada. Sin embargo, el enlace contiene un error según el estándar si el número de entrada es demasiado grande para caber en el tipo de destino, el comportamiento no está definido.

     #include  //the standard C library header #include  int main() { std::string si = "12"; std::string sf = "1.2"; int i = atoi(si.c_str()); //the c_str() function "converts" double f = atof(sf.c_str()); //std::string to const char* } 
  2. Utilice secuencias de cadenas (esta vez ingrese la secuencia de cadenas, istringstream ). De nuevo, istringstream se usa igual que cin . De nuevo, no confundas istringstream con istrstream . Este último está en desuso.

     #include  #include  int main() { std::string inputString = "1234 12.3 44"; std::istringstream istr(inputString); int i1, i2; float f; istr >> i1 >> f >> i2; //i1 is 1234, f is 12.3, i2 is 44 } 
  3. Utilice el reparto léxico de impulso .

     #include  #include  int main() { std::string sf = "42.2"; std::string si = "42"; float f = boost::lexical_cast(sf); //f is 42.2 int i = boost::lexical_cast(si); //i is 42 } 

    En caso de una entrada incorrecta, lexical_cast arroja una excepción de tipo boost::bad_lexical_cast

En C ++ 17, las nuevas funciones std :: to_chars y std :: from_chars se introducen en el encabezado charconv .

std :: to_chars es independiente de la configuración regional, no asigna y no arroja.

Solo se proporciona un pequeño subconjunto de políticas de formato utilizadas por otras bibliotecas (como std :: sprintf).

De std :: a_chars , lo mismo para std :: from_chars .

La garantía de que std :: from_chars puede recuperar todos los valores de coma flotante formateados por to_chars exactamente solo se proporciona si ambas funciones son de la misma implementación

  // See en.cppreference.com for more information, including format control. #include  #include  #include  #include  #include  using Type = /* Any fundamental type */ ; std::size_t buffer_size = /* ... */ ; [[noreturn]] void report_and_exit(int ret, const char *output) noexcept { std::printf("%s\n", output); std::exit(ret); } void check(const std::errc &ec) noexcept { if (ec ==  std::errc::value_too_large) report_and_exit(1, "Failed"); } int main() { char buffer[buffer_size]; Type val_to_be_converted, result_of_converted_back; auto result1 = std::to_chars(buffer, buffer + buffer_size, val_to_be_converted); check(result1.ec); *result1.ptr = '\0'; auto result2 = std::from_chars(buffer, result1.ptr, result_of_converted_back); check(result2.ec); assert(val_to_be_converted == result_of_converted_back); report_and_exit(0, buffer); } 

Aunque no está completamente implementado por los comstackdores, definitivamente será implementado.

Robé esta clase conveniente de algún lado aquí en StackOverflow para convertir cualquier cosa que se pueda transmitir a una cadena:

 // make_string class make_string { public: template  make_string& operator< <( T const & val ) { buffer_ << val; return *this; } operator std::string() const { return buffer_.str(); } private: std::ostringstream buffer_; }; 

Y luego lo usas como;

 string str = make_string() < < 6 << 8 << "hello"; 

¡Bastante ingenioso!

También utilizo esta función para convertir cadenas a cualquier cosa que se pueda transmitir, aunque no es muy seguro si intentas analizar una cadena que no contiene un número; (y no es tan inteligente como el último tampoco)

 // parse_string template  RETURN_TYPE parse_string(const STRING_TYPE& str) { std::stringstream buf; buf < < str; RETURN_TYPE val; buf >> val; return val; } 

Usar como:

 int x = parse_string("78"); 

Es posible que también desee versiones para wstrings.