Есть ли альтернатива для printf? - PullRequest
21 голосов
/ 12 октября 2010

Мне нужно создать программное обеспечение, которое должно работать на нескольких * 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() не вариант.

Ответы [ 4 ]

25 голосов
/ 12 октября 2010

Я не имею в виду быть носителем плохих новостей, но то, что вы предлагаете, на самом деле плохая идея. Я работаю в компании, которая очень серьезно относится к 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}.

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

25 голосов
/ 12 октября 2010

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

printf("Hi %1$s, you are %2$s.", name, status);
printf("Vous êtes %2$s, bonjour %1$s !", name, status);
11 голосов
/ 12 октября 2010

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

9 голосов
/ 12 октября 2010

Требуется расширение% n $ s, которое является общим для большинства систем Unix.

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

См. Пример Германии внизу printf

С уважением, DaveF

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...