Question

(Note: I know of Boost.Format, I'm looking for a better way to do the following.)
First a use-case example: In some countries, you name a person by calling his / her surname first and the forename last, while in other countries it's the exact opposite.

Now, for my code, I currently solve this with Boost.Format in the following fashion:

#include <boost/format.hpp>
#include <iostream>
#include <stdlib.h>
#include <utility>

int main(){
    using namespace boost;

    int pos1 = 2, pos2 = 1;
    char const* surname = "Surname", *forename = "Forename";

    // decision on ordering here
    bool some_condition = false;

    if(some_condition)
      std::swap(pos1,pos2);

    char buf[64];
    sprintf(buf,"Hello %c%d%c %c%d%c",'%',pos1,'%','%',pos2,'%');
    // buf == "Hello %[pos1]% %[pos2]%"; with [posN] = value of posN

    std::cout << format(buf) % surname % forename;
}

Now, I would rather have it like this, i.e., everything in the format line:

std::cout << format("Hello %%1%% %%2%%") % pos1 % pos2 % surname % forename;

But sadly, that doesn't work, as I get a nice parsing exception.

Is there any library to have real positional formatting? Or even a way to achieve this with Boost.Format that I don't know of?

Was it helpful?

Solution

In my opinion, Boost.Spirit.Karma is the definitive modern output formatting library.

OTHER TIPS

This is the Message Formatting part of Boost.Locale which is similar to GNU gettext.

In it you would write:

cout << format(translate("Hello {1} {2}!")) % forename % surname << endl;

And then a translator would translate the string using message catalogs:

msgid "Hello {1} {2}!"
msgstr "こんにちは {2}-さん!"

I'd simply swap the values that you interpolating

std::swap(surname, forename)

That'll do the job. If you don't want to mess with them, have references:

const std::string& param1(bSwapThem? forename : surname);
const std::string& param2(bSwapThem? surname  : forename);

KISS

Sounds like something that should be in the system locale but it doesn't look like it's currently supported.

What about the simple way?

   if(some_condition)
      std::cout << surname << " " << forename;
   else
      std::cout << forename << " " << surname;

I would have used ?:

char const* surname = "Surname", *forename = "Forename";
bool swapFlag = (some_condition) ? true : false;

std::cout << "Hello " << (swapFlag ? surname : forename) << " " << (!swapFlag ? surname : forename) << std::endl;

You can do this by applying format recursively:

cout << format(str(format("%%%1%%% %%%2%%%") % pos1 % pos2)) % surname % forname;

However, I would recommend using something like GNU gettext instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top