cprintf: support a configurable width and precision ("*" in printf)
This commit is contained in:
parent
47e2b08893
commit
74f10be526
4 changed files with 57 additions and 8 deletions
|
@ -40,7 +40,7 @@ using namespace std;
|
|||
namespace cp {
|
||||
|
||||
Print::Print(std::ostream &stream, const std::string &format)
|
||||
: stream(stream), format(format.c_str()), ptr(format.c_str())
|
||||
: stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false)
|
||||
{
|
||||
saved_flags = stream.flags();
|
||||
saved_fill = stream.fill();
|
||||
|
@ -48,7 +48,7 @@ Print::Print(std::ostream &stream, const std::string &format)
|
|||
}
|
||||
|
||||
Print::Print(std::ostream &stream, const char *format)
|
||||
: stream(stream), format(format), ptr(format)
|
||||
: stream(stream), format(format), ptr(format), cont(false)
|
||||
{
|
||||
saved_flags = stream.flags();
|
||||
saved_fill = stream.fill();
|
||||
|
@ -60,8 +60,10 @@ Print::~Print()
|
|||
}
|
||||
|
||||
void
|
||||
Print::process(Format &fmt)
|
||||
Print::process()
|
||||
{
|
||||
fmt.clear();
|
||||
|
||||
size_t len;
|
||||
|
||||
while (*ptr) {
|
||||
|
@ -221,8 +223,15 @@ Print::process(Format &fmt)
|
|||
number = number * 10 + (*ptr - '0');
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (have_precision)
|
||||
fmt.get_precision = true;
|
||||
else
|
||||
fmt.get_width = true;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
assert("we shouldn't get here");
|
||||
assert(false && "we shouldn't get here");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -51,24 +51,53 @@ struct Print
|
|||
std::ostream &stream;
|
||||
const char *format;
|
||||
const char *ptr;
|
||||
bool cont;
|
||||
|
||||
std::ios::fmtflags saved_flags;
|
||||
char saved_fill;
|
||||
int saved_precision;
|
||||
|
||||
void process(Format &fmt);
|
||||
Format fmt;
|
||||
void process();
|
||||
|
||||
public:
|
||||
Print(std::ostream &stream, const std::string &format);
|
||||
Print(std::ostream &stream, const char *format);
|
||||
~Print();
|
||||
|
||||
int
|
||||
get_number(int data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int
|
||||
get_number(const T& data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
add_arg(const T &data)
|
||||
{
|
||||
Format fmt;
|
||||
process(fmt);
|
||||
if (!cont)
|
||||
process();
|
||||
|
||||
if (fmt.get_width) {
|
||||
fmt.get_width = false;
|
||||
cont = true;
|
||||
fmt.width = get_number(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fmt.get_precision) {
|
||||
fmt.get_precision = false;
|
||||
cont = true;
|
||||
fmt.precision = get_number(data);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (fmt.format) {
|
||||
case Format::character:
|
||||
|
|
|
@ -50,6 +50,8 @@ struct Format
|
|||
enum { best, fixed, scientific } float_format;
|
||||
int precision;
|
||||
int width;
|
||||
bool get_precision;
|
||||
bool get_width;
|
||||
|
||||
Format() { clear(); }
|
||||
|
||||
|
@ -65,6 +67,8 @@ struct Format
|
|||
format = none;
|
||||
precision = -1;
|
||||
width = 0;
|
||||
get_precision = false;
|
||||
get_width = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -167,6 +167,13 @@ main()
|
|||
|
||||
cprintf("%c %c\n", 'c', 65);
|
||||
|
||||
cout << '9';
|
||||
cout << '9' << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
cprintf("%08.4f\n", 99.99);
|
||||
cprintf("%0*.*f\n", 8, 4, 99.99);
|
||||
cprintf("%07.*f\n", 4, 1.234);
|
||||
cprintf("%#0*x\n", 9, 123412);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue