Ya que esta duda se le preguntó acerca de cada semana, este Preguntas frecuentes puede ayudar a una gran cantidad de usuarios.

  • Cómo convertir un entero a una cadena en C++

  • cómo convertir una cadena en un entero en C++

  • cómo convertir un número en punto flotante a una cadena en C++

  • cómo convertir una cadena a un número de punto flotante en C++

4 Comentarios

  1. 124

    Actualización para C++11

    Como de la C++11 estándar, de cadena a número de conversión y viceversa están integradas en la biblioteca estándar. Las siguientes funciones están presentes en <string> (según el párrafo 21.5).

    cadena 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 y se vuelva a convertir en un número. Si no hay un número válido podría ser construido, por ejemplo, porque no hay datos numéricos o el número está fuera del rango para el tipo, se produce una excepción (std::invalid_argument o std::out_of_range).

    Si la conversión ha tenido éxito y idx no es 0, idx contendrá el índice del primer carácter que no fue utilizado para la descodificación. Esto podría ser un índice detrás del último carácter.

    Por último, los tipos integrales permiten especificar una base, para los dígitos mayores que 9, el alfabeto se supone (a=10 hasta z=35). Usted puede encontrar más información sobre el formato exacto que puede analizado aquí para los números de punto flotante, enteros y los enteros sin signo.

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

    numéricos para la cadena de

    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, que pase el apropiado tipo numérico y se obtiene una cadena. Para las opciones de formato que debe volver a la de C++03 stringsream opción y el uso corriente de los manipuladores, como se explica en otra respuesta aquí.

    Como se señaló en los comentarios de estas funciones caer a un defecto mantisa precisión que no es probable que la máxima precisión. Si más de precisión que se requiere para su aplicación también es mejor para ir de nuevo a otro formato de cadena procedimientos.

    También hay funciones similares definido que se denominan to_wstring, estos devolverá un std::wstring.

    • std::to_string pierde mucha precisión para los tipos de punto flotante. Por ejemplo double f = 23.4323897462387526; std::string f_str = std::to_string(f); devuelve una cadena de 23.432390. Esto hace que sea imposible para un viaje redondo de valores de punto flotante de utilizar estas funciones.
    • esta es una restricción impuesta por la norma o aplicación específica? Añadiremos a la respuesta. No es que de ida y vuelta de flota a través de cadenas es una buena idea.
    • El C++ norma dice que «Devuelve: Cada función devuelve un objeto string celebración de la representación de caracteres del valor de su argumento de que sería generado por llamar sprintf(buf, fmt, val) con un especificador de formato de «%d», «%u», «%ld», «%lu», «%lld», «%llu», «%f», «%f» o «%Lf», respectivamente, donde buf designa a un interno búfer de caracteres de tamaño suficiente.» eché un vistazo a la C99 estándar para printf y creo que el número de decimales depende de #define DECIMAL_DIG en float.h.
    • Bruce Dawson tiene algunos buenos artículos sobre lo que la precisión es necesaria para la ronda de disparo de números de punto flotante en su blog.
    • Usted dice que «se genera un error.» pero que me confunde. Las excepciones pueden ser lanzadas, los errores pueden ser devueltos, por lo que esa frase me deja dudas acerca de si usted está hablando acerca de las excepciones o errores. Por favor aclarar.
    • No hay nada malo con ida y vuelta de carrozas y se duplica a través de cadenas. Usted necesita un 17 dígitos de la mantisa de doble y una de nueve dígitos de mantisa para flotar, y entonces estás de oro. Si to_string no tiene ninguna opción para producir ronda-trippable variables, a continuación, que son (en mi humilde opinión) roto. Lástima. fun4jimmy que ya se ha añadido un enlace a mi blog donde voy con esto en más detalle.
    • Honestamente no estoy totalmente de acuerdo. No es porque no se puede hacer con un largo suficiente parte fraccionaria es una buena idea. to_string, printf y es igual están destinados para la representación de caracteres (visuallization), no serialización. Sin embargo estoy de acuerdo en que vale la pena mencionar.
    • Creo que está bien para to_string predeterminado para mostrar sólo una aproximación, pero para que incluso de no tener un opción para identificar el número parece terrible. Estas funciones fueron una oportunidad para luchar contra años de confusión. Ah, bueno.
    • Todas estas funciones se ven afectadas por la configuración regional global, lo cual puede llevar a problemas si utiliza las bibliotecas, y especialmente si el uso de hilos. Ver a mi pregunta aquí: stackoverflow.com/questions/31977457/…

  2. 84

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

    1. No utilice la itoa o itof funciones debido a que no son estándar y por lo tanto no portátil.
    2. Uso de la cadena de secuencias

       #include <sstream>  //include this to use string streams
       #include <string> 
      
      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 puede utilizar la cadena de secuencias también para convertir los números de punto flotante a la cadena, y también para dar formato a la cadena como usted desea, 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 utilizar la secuencia de manipuladores, tales como std::endl, std::hex y funciones std::setw(), std::setprecision() etc. con cadena de secuencias en exactamente la misma manera como con cout

      No hay que confundir std::ostringstream con std::ostrstream. El último está en desuso

    3. Uso impulsar el léxico de fundición. Si usted no está familiarizado con el impulso, es una buena idea comenzar con una pequeña biblioteca como este lexical_cast. Para descargar e instalar el impulso y su documentación vaya aquí. Aunque impulso no está en el estándar de C++ muchas bibliotecas de impulsar obtener estandarizado finalmente y boost es ampliamente considerado como una de las mejores bibliotecas de C++.

      Léxico de fundición de los usos corrientes de debajo, así que, básicamente, esta opción es la misma que la anterior, sólo que menos detallado.

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

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

    1. El más ligero opción, heredado de C, es el de las funciones de atoi (para los números enteros (en orden alfabético a integer)) y atof (para los valores de punto flotante (en orden alfabético a float)). Estas funciones toman un C-estilo de la cadena como argumento (const char *) y por lo tanto su uso puede ser considerado como un no exactamente buena C++ práctica. cplusplus.com tiene un fácil-a-entender la documentación en ambos atoi y atof incluyendo cómo se comportan en caso de mal de entrada. Sin embargo, el enlace contiene un error en el que de acuerdo a la norma si el número de entrada es demasiado grande para caber en el tipo de destino, el comportamiento es indefinido.

      #include <cstdlib> //the standard C library header
      #include <string>
      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. Uso de la cadena de corrientes (esta vez de la cadena de entrada corriente, istringstream). De nuevo, istringstream se utiliza como cin. De nuevo, no hay que confundir istringstream con istrstream. El último está en desuso.

      #include <sstream>
      #include <string>
      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. Uso impulsar el léxico de fundición.

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

      En caso de una mala entrada, lexical_cast lanza una excepción de tipo boost::bad_lexical_cast

    • El cplusplus documentación para atoi no es excelente, es incorrecta. Que no se puede mencionar que si el valor numérico de la cadena no puede ser representado en int, entonces, el comportamiento es indefinido. Se dice, en cambio, que fuera-de-rango de valores se sujetan a INT_MAX/INT_MIN, que no puedo encontrar en C++03 o C89. Para los que no son de confianza/verificada de entrada, o cuando se trata de secuencias de bases que no apoyo, usted necesita strtol, que ha definido comportamiento de error. Y comentarios similares para atof/strtod.
    • Siéntase libre de editar en consecuencia 🙂
    • cplusplus.com es incorrecto acerca de «atoi». Que dice sobre el valor de retorno «Si no hay una conversión puede ser realizada, un valor cero se devuelve. Si el valor está fuera del rango de valores representables, INT_MAX o INT_MIN se devuelve.», pero la especificación dice que «Si el valor de la consecuencia no puede ser representado, el comportamiento es indefinido.» y que «Excepto por el comportamiento en caso de error, que son equivalentes a (int)strtol(nptr, (char **)NULL, 10). El atoi[…] de las funciones devuelven el valor convertido.». cplusplus.com es conocido por ser una increíble mala fuente de información para los principiantes.
    • Siéntase libre de editar en consecuencia 🙂
    • istr >> i1 >> f >> i2; mal pierde un cheque para el éxito.
    • Quizás desee agregar std::to_string
    • de mi parte, Uno de los mejor respuesta que he visto que también en profundidad. Gracias por tu respuesta.
    • En realidad boost::lexical_cast sólo utiliza stringstream para los tipos que no sabe acerca de. Para los tipos que se sabe, lexical_cast siempre supera a stringstreams (a menudo por un muy amplio margen). boost.org/doc/libs/1_50_0/doc/html/boost_lexical_cast/…
    • Un punto importante acerca de boost::lexical_cast debe tenerse en cuenta: su manejo de int8_t y uint8_t que esencialmente son considerados como un char(!) que conduce a la más sorpresas desagradables. detalles: boost.org/doc/libs/1_55_0/doc/html/boost_lexical_cast/…

  3. 2

    En C++17, 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, la no asignación,
    y no tirar.

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

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

    La garantía de que std::from_chars se puede recuperar
    cada valor de punto flotante de formato
    por to_chars exactamente se proporciona únicamente si ambos
    las funciones son de la misma aplicación

     //See en.cppreference.com for more information, including format control.
    #include <cstdio>
    #include <cstddef>
    #include <cstdlib>
    #include <cassert>
    #include <charconv>
    
    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 = '
     //See en.cppreference.com for more information, including format control.
    #include <cstdio>
    #include <cstddef>
    #include <cstdlib>
    #include <cassert>
    #include <charconv>
    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);
    }
    '
    ; 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 plenamente por los compiladores, que sin duda será implementado.

  4. 0

    Me robaron este convienent clase de algún lugar aquí en StackOverflow para convertir cualquier cosa streamable a una cadena:

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

    Y, a continuación, utilice como;

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

    Muy ingenioso!

    También puedo usar esta función para convertir cadenas a nada streamable, althrough no es muy seguro si se intenta analizar una cadena no contiene un número;
    (y no es tan inteligente como el último de un bien)

    //parse_string
    template <typename RETURN_TYPE, typename STRING_TYPE>
    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<int>("78");

    También puede ser que desee versiones para wstrings.

    • Esto es exactamente lo que boost::lexical_cast hace. Y el impulso lo hace de una forma más genérica fasion.
    • Cierto, yo desnatada durante la primera respuesta, y no ver el boost::lexical_casts.

Dejar respuesta

Please enter your comment!
Please enter your name here