boost::format your string

Do you use sprintf in your code ?  Did you see it even in  “written in   C++” called code ?   Well, ok it is  way  to format your  numbers  to a string and perhaps it is liked most for its  convenience and ease of use. There are some reasons not to use yout get by experience or by researching the web.

Recently I start using  boost::format   as an alternative to   sprintf.

Suppose you have to program some hardware device for example a motion controller by sending a  dedicated  ASCII character string over some wire interface to trigger certain action like

std::string  command = "PAX=10000;SPX=30000;AMX=100000;BGX";
int ret = device.sendCommand(command); 

Where usally  the character  X for selecting differnt motion stages and any of the numbers can change  during runtime.   So how to do this ?

sprintf

char* commmand;
const char* axis = "X";
sprintf(command,"PA%s=%d;SP%s=%d;AM%s=%d;BG%s",
                axis,
                pos,
                axis,
                speed,
                axis,
                acc,
                axis);
int ret device.sendCommand(std::string(command));

stringstream

std::stringstream stream;
std::string axis ="X";
stream << "PA" 
       << axis 
       << "="
       << pos
       << ";" 
       <<"SP"
       <<axis
       <<"="
       <<speed
       <<";"
       <<"AM"
       <<axis"="
       <<acc
       <<"BG"
       <<axis;
int ret = device.sendCommand(stream.str());

Using  a stringstream object is definitely  type safe C++,  but gets  unhandy and error prone very quick. Especially in this case. You get the point why many people  go for sprintf.

boost::format

With boost::format  it turns out that we can implement the example like  this:

boost::format  cmdMove("PA%1%=%2%;SP%1%=%3%;AM%1%=%4%;BG%1%");
std::string command = (cmdMove % axis % pos % speed % accel).str();

int ret device.sendCommand(command);

First we  create a boost::format  object, which we can reuse or implement as a member in our command classs etc. The ctor takes a string and the variable arguments are marked by so called positional arguments which allows for reuse or reordering. When assiging the command string the arguments are fed with the % operator into the object. The argument axis ( %1%) is used four times in this case, which led to less typing and cleaner code.

With boost::format you can also  realize posix-printf styles, but in a type safe way.

You can find more info  at http://www.boost.org/doc/libs/1_58_0/libs/format/

Leave a Reply