Converti un numero in una stringa con la lunghezza specificata in C ++
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 ++?
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.