Troncature des champs de chaîne C de produits par ostringstream, iomanip: setw
-
04-10-2019 - |
Question
En C ++ I représentations de chaîne besoin d'entiers avec des zéros non significatifs, où la représentation a 8 chiffres et pas plus de 8 chiffres, troncature chiffres sur le côté droit, si nécessaire. Je pensais que je pouvais le faire en utilisant seulement ostringstream et iomanip.setw (), comme ceci:
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;
La sortie ici est:
field: 00003000 vs input: 3000
Très beau! Toutefois, si je tente un plus grand nombre, permet setw GROW de sortie au-delà de 8 caractères:
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("");
sortie:
field: 2000000000 vs input: 2000000000
La sortie souhaitée est "20000000". Il n'y a rien qui me empêche d'utiliser une deuxième opération pour ne prendre que les 8 premiers caractères, mais est troncature sur le terrain vraiment manque de iomanip? Est-ce que le formatage Boost faire ce que je dois en une seule étape?
La solution
Je ne peux pas penser à une façon de tronquer un champ numérique comme ça. Peut-être qu'il n'a pas été mis en œuvre parce qu'il changerait la valeur.
ostream::write()
vous permet de tronquer string tampon assez simplement, comme dans cet exemple ...
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;
Autres conseils
Si vous supposez que snprintf () va écrire autant de caractères à elle peut (je ne pense pas que cela est garanti),
char buf[9];
snprintf(buf, 10, "%08d", num);
buf[8] = 0;
cout << std::string(buf) << endl;
Je ne sais pas pourquoi vous voulez 2 milliards d'être le même que 20 millions. Il peut être plus judicieux pour signaler une erreur sur troncature, comme ceci:
if (snprintf(buf, 10, "%08d", num) > 8) {
throw std::exception("oops")
}