Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

Me preguntaba si había una alternativa a itoa() para convertir un número entero en una cadena porque cuando lo ejecuto en Visual Studio recibo advertencias, y cuando trato de construir mi programa en Linux, recibo un error de compilación .

¿Fue útil?

Solución

En C ++ 11 puede usar std::to_string :

#include <string>

std::string s = std::to_string(5);

Si está trabajando antes de C ++ 11, puede usar transmisiones de C ++:

#include <sstream>

int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();

Tomado de http: //notfaq.wordpress .com / 2006/08/30 / c-convert-int-to-string /

Otros consejos

boost :: lexical_cast funciona bastante bien.

#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
    std::string foo = boost::lexical_cast<std::string>(argc);
}

Arqueología

itoa era una función auxiliar no estándar diseñada para complementar la función estándar atoi, y probablemente ocultaba un sprintf (la mayoría de sus características se pueden implementar en términos de sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html

El Camino C

Usa sprintf. O snprintf. O cualquier herramienta que encuentres.

A pesar del hecho de que algunas funciones no están en el estándar, como se menciona con razón por " onebyone " en uno de sus comentarios, la mayoría del compilador le ofrecerá una alternativa (por ejemplo, Visual C ++ tiene su propio _snprintf, puede escribir def a snprintf si lo necesita).

La forma de C ++.

Utilice las secuencias de C ++ (en el caso actual std :: stringstream (o incluso la obsoleta std :: strstream, como lo propone Herb Sutter en uno de sus libros, porque es algo más rápido).

Conclusión

Estás en C ++, lo que significa que puedes elegir la forma que quieras:

  • La forma más rápida (es decir, la forma C), pero debe estar seguro de que el código es un cuello de botella en su aplicación (las optimizaciones prematuras son malas, etc.) y que su código está encapsulado de forma segura para evitar el riesgo de desbordamiento del búfer .

  • La forma más segura (es decir, la forma C ++), si sabe que esta parte del código no es crítica, así que mejor asegúrese de que esta parte del código no se rompa en momentos aleatorios porque alguien confundió un tamaño o un puntero (que sucede en la vida real, como ... ayer, en mi computadora, porque alguien pensó & "; genial &"; usar la forma más rápida sin realmente necesitarla).

Pruebe sprintf ():

char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"

sprintf () es como printf () pero da salida a una cadena.

Además, como mencionó Parappa en los comentarios, es posible que desee usar snprintf () para evitar que se produzca un desbordamiento del búfer (donde el número que está convirtiendo no se ajusta al tamaño de su cadena). Funciona así :

snprintf(str, sizeof(str), "%d", num);

Detrás de escena, lexical_cast hace esto:

std::stringstream str;
str << myint;
std::string result;
str >> result;

Si no quiere " arrastre " impulso para esto, entonces usar lo anterior es una buena solución.

Podemos definir nuestra propia función iota en c ++ como:

string itoa(int a)
{
    string ss="";   //create empty string
    while(a)
    {
        int x=a%10;
        a/=10;
        char i='0';
        i=i+x;
        ss=i+ss;      //append new character at the front of the string!
    }
    return ss;
}

No olvides #include <string>.

& # 1057; ++ 11 finalmente resuelve esto proporcionando std::to_string . También boost::lexical_cast es una herramienta útil para compiladores antiguos.

Utilizo estas plantillas

template <typename T> string toStr(T tmp)
{
    ostringstream out;
    out << tmp;
    return out.str();
}


template <typename T> T strTo(string tmp)
{
    T output;
    istringstream in(tmp);
    in >> output;
    return output;
}

Pruebe Boost.Format o FastFormat , ambas bibliotecas C ++ de alta calidad:

int i = 10;
std::string result;

Con Boost.Format

result = str(boost::format("%1%", i));

o FastFormat

fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);

Obviamente, ambos hacen mucho más que una simple conversión de un entero entero

Puede convertir cualquier cosa en una cadena con una función de plantilla escrita de forma inteligente. Este ejemplo de código usa un bucle para crear subdirectorios en un sistema Win-32. El operador de concatenación de cadenas, operador +, se utiliza para concatenar una raíz con un sufijo para generar nombres de directorio. El sufijo se crea convirtiendo la variable de control de bucle, i, en una cadena de C ++, usando la función de plantilla, y concatenando eso con otra cadena.

//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology

#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>

using namespace std;

string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an   */
/* integer as input and as output,    */
/* returns a C++ string.              */
/* itoa()  returned a C-string (null- */
/* terminated)                        */
/* This function is not needed because*/
/* the following template function    */
/* does it all                        */
/**************************************/   
       string r;
       stringstream s;

       s << x;
       r = s.str();

       return r;

}

template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of   */
/* C++ templates. This function will  */
/* convert anything to a string!      */
/* Precondition:                      */
/* operator<< is defined for type T    */
/**************************************/
       string r;
       stringstream s;

       s << argument;
       r = s.str();

       return r;

}

int main( )
{
    string s;

    cout << "What directory would you like me to make?";

    cin >> s;

    try
    {
      mkdir(s.c_str());
    }
    catch (exception& e) 
    {
      cerr << e.what( ) << endl;
    }

    chdir(s.c_str());

    //Using a loop and string concatenation to make several sub-directories
    for(int i = 0; i < 10; i++)
    {
        s = "Dir_";
        s = s + toString(i);
        mkdir(s.c_str());
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}

Asigne una cadena de longitud suficiente, luego use snprintf.

La mejor respuesta, IMO, es la función proporcionada aquí:

http://www.jb.man.ac.uk /~slowe/cpp/itoa.html

Imita la función no ANSI proporcionada por muchas bibliotecas.

char* itoa(int value, char* result, int base);

También es rápido como un rayo y se optimiza bien bajo -O3, y la razón por la que no estás usando c ++ string_format () ... o sprintf es que son demasiado lentos, ¿verdad?

Tenga en cuenta que todos los stringstream métodos pueden implicar bloquear el uso del objeto de configuración regional para formatear. Esto puede ser algo de lo que debe tener cuidado si está utilizando esta conversión desde múltiples hilos ...

Ver aquí para más. Convierta un número en una cadena con una longitud especificada en C ++

int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;

Si está interesado en el método de conversión de entero a cadena rápido y seguro y no se limita a la biblioteca estándar, puedo recomendar el método FormatInt de Biblioteca de formato C ++ :

fmt::FormatInt(42).str();   // convert to std::string
fmt::FormatInt(42).c_str(); // convert and get as a C string
                            // (mind the lifetime, same as std::string::c_str())

Según el puntos de referencia de conversión de entero a cadena de Boost Karma, este método varias veces más rápido que el sprintf o std::stringstream de glibc. Es incluso más rápido que el propio Boost Karma int_generator como lo confirmó un punto de referencia independiente .

Descargo de responsabilidad: soy el autor de esta biblioteca.

Escribí esta función segura para subprocesos hace algún tiempo, y estoy muy contento con los resultados y siento que el algoritmo es liviano y delgado, con un rendimiento que es aproximadamente 3 veces la función estándar de MSVC _itoa () .

Aquí está el enlace. Función óptima de Base-10 solo itoa ()? El rendimiento es al menos 10X que de sprintf (). El punto de referencia es también la prueba de control de calidad de la función, de la siguiente manera.

start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
    if (i != atoi(_i32toa(buff, (int32_t)i))) {
        printf("\nError for %i", i);
    }
    if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));

Hay algunas sugerencias tontas sobre el uso del almacenamiento de la persona que llama que dejaría el resultado flotando en algún lugar en un búfer en el espacio de direcciones de la persona que llama. Ingnóralos. El código que enumeré funciona perfectamente, como lo demuestra el código de referencia / control de calidad.

Creo que este código es lo suficientemente delgado como para usarlo en un entorno incrustado. YMMV, por supuesto.

En las plataformas derivadas de Windows CE, no hay iostream s por defecto. El camino a seguir es preferiblemente con la familia _itoa<>, generalmente _itow<> (ya que la mayoría de las cadenas son Unicode de todos modos).

La mayoría de las sugerencias anteriores no son técnicamente C ++, son soluciones C.

Considere el uso de std :: stringstream .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top