Domanda

Ho alcuni numeri di diversa lunghezza (come 1, 999, 76492, ecc.) e voglio convertirli tutti in stringhe con una lunghezza comune (ad esempio, se la lunghezza è 6, tali stringhe saranno: '000001', '000999', '076492').

In altre parole, devo aggiungere una quantità corretta di zeri iniziali al numero.

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

Esiste una funzione come questa in C ++?

È stato utile?

Soluzione

o usando gli stringstreams:

#include <sstream>
#include <iomanip>

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

Ho compilato le informazioni che ho trovato su arachnoid.com perché mi piace il tipo- modo sicuro di iostreams di più. Inoltre, puoi anche usare questo codice su qualsiasi altro flusso di output.

Altri suggerimenti

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

Vedi snprintf

Una cosa di cui potresti essere consapevole è il potenziale blocco che potrebbe verificarsi quando usi l'approccio stringstream . Nell'STL fornito con Visual Studio 2008, almeno, ci sono molti blocchi rimossi e rilasciati poiché durante la formattazione vengono utilizzate varie informazioni sulla locale. Questo potrebbe essere o meno un problema per te a seconda del numero di thread che potresti convertire contemporaneamente i numeri in stringhe ...

La versione sprintf non accetta alcun blocco (almeno secondo lo strumento di monitoraggio dei blocchi che sto sviluppando in questo momento ...) e quindi potrebbe essere "migliore" per l'uso in situazioni simultanee.

L'ho notato solo perché il mio strumento recentemente ha sputato i blocchi 'locale' come uno dei blocchi più contesi nel mio sistema server; è stato un po 'una sorpresa e potrebbe farmi rivedere l'approccio che ho seguito (ovvero tornare indietro a sprintf da stringstream ) ...

stringstream farà ( as xtofl sottolineato ). Formato boost è più conveniente sostituzione per snprintf.

Questo metodo non utilizza stream né sprintf. Oltre ad avere problemi di blocco, i flussi comportano un sovraccarico di prestazioni ed è davvero eccessivo. Per i flussi, il sovraccarico deriva dalla necessità di costruire il buffer di vapore e flusso. Per sprintf, il sovraccarico deriva dalla necessità di interpretare la stringa di formato. Funziona anche quando n è negativo o quando la rappresentazione in stringa di n è più lunga di len . Questa è la soluzione PIÙ VELOCE.

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

Esistono molti modi per farlo. Il più semplice sarebbe:

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

sprintf è il modo simile a C per farlo, che funziona anche in C ++.

In C ++, una combinazione di stringstream e formattazione dell'output di stream (vedi http: // www .arachnoid.com / cpptutor / student3.html ) farà il lavoro.

Questo è un vecchio thread, ma come fmt potrebbe trasformarlo nello standard, qui è una soluzione aggiuntiva:

#include <fmt/format.h>

int n = 999;

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

Nota che fmt :: format (" {: 0 > 6} " ;, n) funziona ugualmente bene quando la larghezza desiderata è nota al momento della compilazione. Un'altra opzione è abseil :

#include <absl/strings/str_format.h>

int n = 999;

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

Ancora una volta, abs :: StrFormat ("% 06d " ;, n) è possibile. boost format è un altro strumento per questo problema:

#include <boost/format.hpp>

int n = 999;

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

Sfortunatamente, l'identificatore a larghezza variabile come argomenti concatenati con l'operatore % non è supportato, ciò richiede una configurazione della stringa di formato (ad es. const std :: string fmt = "% 0 " + std :: to_string (6) + " d " ;; ).

In termini di prestazioni, la doppia e la fmt dichiarano di essere molto attraenti e più veloci della spinta. In ogni caso, tutte e tre le soluzioni dovrebbero essere più efficienti degli approcci std :: stringstream e, oltre alla famiglia std :: * printf , non sacrificano la sicurezza dei tipi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top