Подтвердить что ты не робот

Есть ли альтернатива для printf?

Мне нужно создать программное обеспечение, которое должно работать на нескольких платформах * nix (Linux, AIX,...).

Мне нужно обработать интернационализацию, и мои строки перевода имеют следующий вид:

"Hi %1, you are %2." // English
"Vous êtes %2, bonjour %1 !" // French

Здесь %1 укажите имя и %2 для другого слова. Я могу изменить формат, это не проблема.

Я попытался использовать printf(), но вы не можете указать порядок параметров, просто укажите их типы.

"Hi %s, you are %s"
"Vous êtes %s, bonjour %s !"

Теперь нет способа узнать, какой параметр использовать для замены %s: printf() использует только первый, затем следующий.

Есть ли альтернатива printf(), которая имеет дело с этим?

Примечание: gettext() не является параметром.

4b9b3361

Ответ 1

POSIX printf() поддерживает позиционные аргументы.

printf("Hi %1$s, you are %2$s.", name, status);
printf("Vous êtes %2$s, bonjour %1$s !", name, status);

Ответ 2

Я не хочу быть носителем плохих новостей, но то, что вы предлагаете, на самом деле плохая идея. Я работаю в компании, которая очень серьезно относится к i18n, и мы обнаружили (больно), что вы не можете просто сложить слова в такие предложения, поскольку они часто не имеют никакого смысла.

Что мы делаем, так это просто полностью отключить текст ошибки от переменных битов, чтобы избежать этих проблем. Например, мы создадим ошибку:

XYZ-E-1002 Frobozz not configured for multiple zorkmids (F22, 7).

И затем, в описании ошибки, вы просто заявляете, что два значения в круглых скобках в конце - это идентификатор Frobozz и количество zorkmids, которое вы пытались нанести на него.

Это оставляет перевод i18n как невероятно легкую задачу, поскольку у вас есть время перевода, все необходимые вам элементы языка, не беспокоясь о том, должны ли переменные биты быть единичными или множественными, мужскими или женскими, первым, вторым или третьим склонением (что бы это ни означало).

Команда перевода просто должна конвертировать "Frobozz not configured for multiple zorkmids", и это намного проще.


Для тех, кто хотел бы увидеть конкретный пример, у меня есть что-то от наших переводчиков (с достаточным количеством материалов для защиты виновных).

В какой-то момент кто-то представил следующее:

The {name} {object} is invalid

где {name} - имя объекта (клиенты, заказы и т.д.), а {object} - сам тип объекта (таблица, файл, документ, хранимая процедура и т.д.).

Достаточно просто для английского, основного (возможно, только) языка разработчиков, но они столкнулись с проблемой при переводе на немецкий/швейцарский-немецкий.

В то время как "документ клиентов" правильно переведен (в позиционном смысле) на Kundendokument, проблема в том, что строка формата имела пробел между двумя словами. Это было в основном потому, что разработчики пытались сделать предложение более естественным, но, к сожалению, только более естественным, основанным на их ограниченном опыте.

Большая проблема заключалась в "хранимой процедуре клиентов", которая стала gespeichertes Verfahren der Kunden, буквально "хранимой процедурой клиентов". Хотя немецкие клиенты могут сместиться с пробелом в Kunden dokument, невозможно навязать gespeichertes Verfahren der Kunden на {name} {object} успешно.

Теперь вы можете сказать, что более чистая строка формата исправила бы это, но есть несколько причин, по которым это было бы неверно:

  • Это очень простой пример, скорее всего, другие будут более сложными (я бы попытался получить несколько примеров, но наши переводчики дали понять, что они имеют более насущную работу, чем подчиняться моей прихоти).
  • Весь смысл строк формата заключается в экстернализации перевода. Если сами строки формата являются специфическими для цели перевода, вы получили очень мало, вытесняя текст. Разработчики
  • не должны беспокоиться о строках формата, например {possible-pre-adjectives} {possible-pre-owner} {object} {possible-post-adjectives} {possible-post-owner} {possible-postowner-adjectives}. Это работа команд перевода, поскольку они понимают нюансы.

Обратите внимание, что введение разъединения устраняет эту проблему:

The object specified by <parameter 1>, of type <parameter 2>, is invalid.
    Parameter 1 = {name}.
    Parameter 2 = {object}.
Der sache nannte <parameter 1>, dessen art <parameter 2> ist, ist falsch. 
    Parameter 1 = {name}.
    Parameter 2 = {object}.

Этот последний перевод был одним из моих, пожалуйста, не используйте его, чтобы ослабить качество наших переводчиков. Без сомнения, более свободно говорящие немцы получат хороший отклик.

Ответ 3

boost.format поддерживает этот способ, как в python, однако это для С++

Ответ 4

Вы хотите, чтобы расширение% n $s было общим для большинства Unix-систем.

"Hi %1$s, you are %2$s."

Смотрите немецкий пример внизу printf

Отношения DaveF