Tronca C ++ campi stringa generata dal ostringstream, iomanip: setw
-
04-10-2019 - |
Domanda
rappresentazioni di stringa in C ++ ho bisogno di interi con zeri iniziali, in cui la rappresentazione dispone di 8 cifre e non più di 8 cifre, truncating cifre sul lato destro, se necessario. Ho pensato che avrei potuto fare questo utilizzando solo ostringstream e iomanip.setw (), in questo modo:
int num_1 = 3000;
ostringstream out_target;
out_target << setw(8) << setfill('0') << num_1;
cout << "field: " << out_target.str() << " vs input: " << num_1 << endl;
L'output è:
field: 00003000 vs input: 3000
Molto bello! Tuttavia se provo un numero più grande, lascia setw il crescere di uscita al di là di 8 caratteri:
int num_2 = 2000000000;
ostringstream out_target;
out_target << setw(8) << setfill('0') << num_2;
cout << "field: " << out_target.str() << " vs input: " << num_2 << endl;
out_target.str("");
uscita:
field: 2000000000 vs input: 2000000000
L'output desiderato è "20000000". Non c'è niente mi impedisce di utilizzare una seconda operazione di prendere solo i primi 8 caratteri, ma è il campo troncamento veramente manca iomanip? Sarebbe il Boost formattazione fare quello che mi serve in un solo passo?
Soluzione
Non riesco a pensare a un modo per troncare un campo numerico del genere. Forse non è stata implementata perché sarebbe cambiare il valore.
ostream::write()
consente di troncare una stringa tampone abbastanza semplice, come in questo esempio ...
int num_2 = 2000000000;
ostringstream out_target;
out_target << setw(8) << setfill('0') << num_2;
cout << "field: ";
cout.write(out_target.str().c_str(), 8);
cout << " vs input: " << num_2 << endl;
Altri suggerimenti
Se si assume che snprintf () scriverà il maggior numero di caratteri a esso può (non credo che questo è garantito),
char buf[9];
snprintf(buf, 10, "%08d", num);
buf[8] = 0;
cout << std::string(buf) << endl;
Non sono sicuro perché si vuole 2 miliardi di essere lo stesso di 20 milioni. Si potrebbe avere più senso per segnalare un errore di troncamento, in questo modo:
if (snprintf(buf, 10, "%08d", num) > 8) {
throw std::exception("oops")
}