Реальное позиционное форматирование строки?

(Примечание: я знаю о Boost.Format, я ищу лучший способ сделать следующее.)
Первый пример варианта использования: в некоторых странах вы называете человека, называя его / ее фамилию первой и фамилию фамилией, в то время как в других странах это полная противоположность.

Теперь для своего кода я решаю эту проблему с помощью Boost.Format следующим образом:

#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;
}

Теперь я предпочел бы, чтобы это было так, т.е. все в format линия:

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

Но, к сожалению, это не работает, так как я получаю приятное исключение при разборе.

Есть ли библиотека для реального позиционного форматирования? Или даже способ достичь этого с Boost.Format, о котором я не знаю?

6 ответов

Решение

На мой взгляд, Boost. Дух Карма является окончательной современной библиотекой форматирования вывода.

Это часть форматирования сообщений в Boost.Locale, которая похожа на GNU gettext.

В нем вы бы написали:

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

И тогда переводчик переводит строку, используя каталоги сообщений:

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

Вы можете сделать это, применив формат рекурсивно:

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

Тем не менее, я бы рекомендовал использовать что-то вроде GNU gettext.

Похоже, что-то должно быть в системной локали, но не похоже, что в настоящее время поддерживается.

Как насчет простого способа?

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

Я бы просто поменял значения, которые вы интерполировали

std::swap(surname, forename)

Это сделает работу. Если вы не хотите связываться с ними, имейте ссылки:

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

ПОЦЕЛУЙ

Я бы использовал?

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

std::cout << "Hello " << (swapFlag ? surname : forename) << " " << (!swapFlag ? surname : forename) << std::endl;
Другие вопросы по тегам