开发者

Real positional string formatting?

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜