Truncate C++ string fields generated by ostringstream, iomanip:setw
-
04-10-2019 - |
Pergunta
In C++ I need string representations of integers with leading zeroes, where the representation has 8 digits and no more than 8 digits, truncating digits on the right side if necessary. I thought I could do this using just ostringstream and iomanip.setw(), like this:
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;
The output here is:
field: 00003000 vs input: 3000
Very nice! However if I try a bigger number, setw lets the output grow beyond 8 characters:
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("");
output:
field: 2000000000 vs input: 2000000000
The desired output is "20000000". There's nothing stopping me from using a second operation to take only the first 8 characters, but is field truncation truly missing from iomanip? Would the Boost formatting do what I need in one step?
Solução
I can't think of any way to truncate a numeric field like that. Perhaps it has not been implemented because it would change the value.
ostream::write()
allows you to truncate a string buffer simply enough, as in this example...
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;
Outras dicas
If you assume that snprintf() will write as many chars at it can (I don't think this is guaranteed),
char buf[9];
snprintf(buf, 10, "%08d", num);
buf[8] = 0;
cout << std::string(buf) << endl;
I am not sure why you want 2 billion to be the same as 20 million. It may make more sense to signal an error on truncation, like this:
if (snprintf(buf, 10, "%08d", num) > 8) {
throw std::exception("oops")
}