tags:

views:

98

answers:

2

I am trying to use width and precision specifiers with boost::format, like this:

#include <boost\format.hpp>
#include <string>

int main()
{
    int n = 5;
    std::string s = (boost::format("%*.*s") % (n*2) % (n*2) % "Hello").str();
    return 0;
}

But this doesn't work because boost::format doesn't support the * specifier. Boost throws an exception when parsing the string.

Is there a way to accomplish the same goal, preferably using a drop-in replacement?

+1  A: 

Well, this isn't a drop-in, but one way to do it would be to construct the format string dynamically:

#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>

int main()
{
    int n = 5;
    const std::string f("%" + 
                        boost::lexical_cast<std::string>(n * 2) + "." +
                        boost::lexical_cast<std::string>(n * 2) + "s");
    std::string s = (boost::format(f) % "Hello").str();
}

Of course, if you did this frequently, you could refactor construction of the format string into a function.

You could also use boost::format() to generate the format string; it's shorter, but potentially less readable, especially for long format strings:

const std::string f = (boost::format("%%%d.%ds") % (n*2) % (n*2)).str();
std::string s = (boost::format(f) % "Hello").str();

(credit to Ferruccio for posting the second idea in the comments)

James McNellis
Yeah, this is so far the best alternative I've been able to come up with. As you may have imagined, I'm refactoring old code. Some of these strings are super complex, and doing it this way would work, but would be very difficult. +1 anyway
John Dibling
Why not use boost::format to generate the format string as well? i.e. std::string f = (boost::format("%%%d.%ds") % n*2 % n*2).str();
Ferruccio
+3  A: 

Try this:

#include <boost/format.hpp>
#include <iomanip>

using namespace std;
using namespace boost;

int main()
{
    int n = 5;
    string s = (format("%s") % io::group(setw(n*2), setprecision(n*2), "Hello")).str();
    return 0;
}

group() lets you encapsulate one or more io manipulators with a parameter.

Ferruccio
This is what I went with, but I'm trying to do this another way, too. See here: http://stackoverflow.com/questions/2981724/boostfunction-boostlambda-again
John Dibling
BTW thanks for pointing me to `group`
John Dibling