Pregunta

Tengo algunos números de diferente longitud (como 1, 999, 76492, etc.) y quiero convertirlos todos a cadenas con una longitud común (por ejemplo, si la longitud es 6, entonces esas cadenas serán: '000001', '000999', '076492').

En otras palabras, debo agregar la cantidad correcta de ceros iniciales al número.

int n = 999;
string str = some_function(n,6);
//str = '000999'

¿Existe una función como esta en C ++?

¿Fue útil?

Solución

o usando las cadenas de cadenas:

#include <sstream>
#include <iomanip>

std::stringstream ss;
ss << std::setw(10) << std::setfill('0') << i;
std::string s = ss.str();

Compilé la información que encontré en arachnoid.com porque me gusta el tipo- Manera segura de iostreams más. Además, también puede utilizar este código en cualquier otro flujo de salida.

Otros consejos

char str[7];
snprintf (str, 7, "%06d", n);

Consulte snprintf

Una cosa que puede tener en cuenta es el bloqueo potencial que puede producirse cuando se utiliza el enfoque stringstream . En la STL que se incluye con Visual Studio 2008, al menos, se eliminan y liberan muchos bloqueos, ya que se usa información de varias configuraciones regionales durante el formateo. Esto puede, o no, ser un problema para usted, dependiendo de la cantidad de subprocesos que tenga que puedan estar convirtiendo simultáneamente números en cadenas ...

La versión sprintf no tiene ningún bloqueo (al menos de acuerdo con la herramienta de monitoreo de bloqueo que estoy desarrollando en este momento ...) por lo que podría ser 'mejor' para usar en situaciones concurrentes.

Solo noté esto porque mi herramienta recientemente escupió los bloqueos 'locale' como uno de los más concurridos por los bloqueos en mi sistema de servidor; fue una sorpresa y podría hacerme revisar el enfoque que he estado tomando (es decir, volver a sprintf desde stringstream ) ...

stringstream hará ( as xtofl señaló ). Boost format es un más conveniente reemplazo para snprintf.

Este método no usa streams ni sprintf. Aparte de tener problemas de bloqueo, los flujos incurren en una sobrecarga de rendimiento y son realmente una exageración. Para flujos, la sobrecarga proviene de la necesidad de construir el buffer de vapor y flujo. Para sprintf, la sobrecarga proviene de la necesidad de interpretar la cadena de formato. Esto funciona incluso cuando n es negativo o cuando la representación de cadena de n es más larga que len . Esta es la solución MÁS RÁPIDA.

inline string some_function(int n, int len)
{
    string result(len--, '0');
    for (int val=(n<0)?-n:n; len>=0&&val!=0; --len,val/=10)
       result[len]='0'+val%10;
    if (len>=0&&n<0) result[0]='-';
    return result;
}

Hay muchas maneras de hacer esto. El más simple sería:

int n = 999;
char buffer[256]; sprintf(buffer, "%06d", n);
string str(buffer);

sprintf es la forma en C de hacer esto, que también funciona en C ++.

En C ++, una combinación de cadena de caracteres y formato de salida de flujo (consulte http: // www .arachnoid.com / cpptutor / student3.html ) hará el trabajo.

Este es un hilo antiguo, pero como fmt puede convertirse en el estándar, aquí es una solución adicional:

#include <fmt/format.h>

int n = 999;

const auto str = fmt::format("{:0>{}}", n, 6);

Tenga en cuenta que el fmt :: format (" {: 0 > 6} " ;, n) funciona igual de bien cuando se conoce el ancho deseado en el momento de la compilación. Otra opción es abseil :

#include <absl/strings/str_format.h>

int n = 999;

const auto str = absl::StrFormat("%0*d", 6, n);

De nuevo, es posible abs :: StrFormat ("% 06d " ;, n) . boost format es otra herramienta para este problema:

#include <boost/format.hpp>

int n = 999;

const auto str = boost::str(boost::format("%06d") % n);

Lamentablemente, el especificador de ancho variable como argumentos encadenados con el operador % no es compatible, esto requiere una configuración de cadena de formato (por ejemplo, const std :: string fmt = "% 0 " + std :: to_string (6) + " d " ;; ).

En términos de rendimiento, el descontento y la demanda afirman ser muy atractivos y más rápidos que el impulso. En cualquier caso, las tres soluciones deberían ser más eficientes que los enfoques de std :: stringstream , y además de la familia std :: * printf , no sacrifican la seguridad de tipo.

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