Old said:
You make it sound so easy
That would be because it actually *is* easy! The only tricky part is
the actual formatting since the above is hardly a specification. Here
is some sample code:
| #include <locale>
| #include <iostream>
| #include <sstream>
| #include <algorithm>
|
| struct my_num_put:
| std::num_put<char>
| {
| iter_type do_put(iter_type to, std::ios_base& fmt,
| char fill, long double d) const
| {
| std:
stringstream out;
| out.precision(1);
| out << std::fixed;
| if (d < 1024.0)
| out << d << " Bytes";
| else if (d < 1024.0 * 1024.0)
| out << (d / 1024.0) << " Kilobytes";
| else if (d < 1024.0 * 1024.0 * 1024.0)
| out << (d / (1024.0 * 1024.0)) << " Megabytes";
| else if (d < 0.5 * 1024.0 * 1024.0 * 1024.0 * 1024.0)
| out << (d / (1024.0 * 1024.0 * 1024.0)) << " Gigabytes";
| else
| out << (d / (1024.0 * 1024.0 * 1024.0 * 1024.0))
| << " Terabytes";
|
| std::string const& s = out.str();
| return std::copy(s.begin(), s.end(), to);
| }
| iter_type do_put(iter_type to, std::ios_base& fmt,
| char fill, double d) const
| {
| return do_put(to, fmt, fill, static_cast<long double>(d));
| }
| };
|
| int main()
| {
| std::locale loc;
| std::locale my_loc(loc, new my_num_put);
| std::cout.imbue(my_loc);
|
| std::cout << 1000.0 << "\n";
| std::cout << 1600.0 << "\n";
| std::cout << 2500000.0 << "\n";
| std::cout << 550000000000.0 << "\n";
| }
This is hardly rocket science...
Note a. that this code does indeed just what I decribed before and b.
most of the work goes into actually figuring out the right format. But
even then, it is no big deal.
BTW, if you want to have something like this which you could turn
on/off
at will, you would have to set formatting flags in the stream object to
tell the stream when you want which formatting. The location to store
e.g. a flag is in an 'int' object accessed using the stream's 'iword()'
object. However, this is no big deal either...