(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?

有帮助吗?

解决方案

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

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top