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 {
|
namespace cp {
|
||||||
|
|
||||||
Print::Print(std::ostream &stream, const std::string &format)
|
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_flags = stream.flags();
|
||||||
saved_fill = stream.fill();
|
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)
|
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_flags = stream.flags();
|
||||||
saved_fill = stream.fill();
|
saved_fill = stream.fill();
|
||||||
|
@ -60,8 +60,10 @@ Print::~Print()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Print::process(Format &fmt)
|
Print::process()
|
||||||
{
|
{
|
||||||
|
fmt.clear();
|
||||||
|
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
while (*ptr) {
|
while (*ptr) {
|
||||||
|
@ -221,8 +223,15 @@ Print::process(Format &fmt)
|
||||||
number = number * 10 + (*ptr - '0');
|
number = number * 10 + (*ptr - '0');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
if (have_precision)
|
||||||
|
fmt.get_precision = true;
|
||||||
|
else
|
||||||
|
fmt.get_width = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case '%':
|
case '%':
|
||||||
assert("we shouldn't get here");
|
assert(false && "we shouldn't get here");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -51,24 +51,53 @@ struct Print
|
||||||
std::ostream &stream;
|
std::ostream &stream;
|
||||||
const char *format;
|
const char *format;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
|
bool cont;
|
||||||
|
|
||||||
std::ios::fmtflags saved_flags;
|
std::ios::fmtflags saved_flags;
|
||||||
char saved_fill;
|
char saved_fill;
|
||||||
int saved_precision;
|
int saved_precision;
|
||||||
|
|
||||||
void process(Format &fmt);
|
Format fmt;
|
||||||
|
void process();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Print(std::ostream &stream, const std::string &format);
|
Print(std::ostream &stream, const std::string &format);
|
||||||
Print(std::ostream &stream, const char *format);
|
Print(std::ostream &stream, const char *format);
|
||||||
~Print();
|
~Print();
|
||||||
|
|
||||||
|
int
|
||||||
|
get_number(int data)
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int
|
||||||
|
get_number(const T& data)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
add_arg(const T &data)
|
add_arg(const T &data)
|
||||||
{
|
{
|
||||||
Format fmt;
|
if (!cont)
|
||||||
process(fmt);
|
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) {
|
switch (fmt.format) {
|
||||||
case Format::character:
|
case Format::character:
|
||||||
|
|
|
@ -50,6 +50,8 @@ struct Format
|
||||||
enum { best, fixed, scientific } float_format;
|
enum { best, fixed, scientific } float_format;
|
||||||
int precision;
|
int precision;
|
||||||
int width;
|
int width;
|
||||||
|
bool get_precision;
|
||||||
|
bool get_width;
|
||||||
|
|
||||||
Format() { clear(); }
|
Format() { clear(); }
|
||||||
|
|
||||||
|
@ -65,6 +67,8 @@ struct Format
|
||||||
format = none;
|
format = none;
|
||||||
precision = -1;
|
precision = -1;
|
||||||
width = 0;
|
width = 0;
|
||||||
|
get_precision = false;
|
||||||
|
get_width = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,13 @@ main()
|
||||||
|
|
||||||
cprintf("%c %c\n", 'c', 65);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue