2010-10-12 4 views
20

Je dois créer un logiciel qui doit fonctionner sur plusieurs plateformes * nix (Linux, AIX, ...).Existe-t-il une alternative pour printf?

J'ai besoin pour gérer l'internationalisation et mes chaînes de traduction sont sous la forme suivante:

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

Ici %1 support pour le nom et %2 pour un autre mot. Je peux changer le format, ce n'est pas un problème.

J'ai essayé d'utiliser printf() mais vous ne pouvez pas spécifier l'ordre des paramètres, il vous suffit de spécifier leurs types.

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

Maintenant, il n'y a aucun moyen de savoir quel paramètre à utiliser pour le remplacement de %s: printf() utilise seulement la première, puis la suivante.

Existe-t-il une alternative à printf() qui traite de cela?

Remarque: gettext() n'est pas une option.

+0

Utilisez une autre langue? Python fait cela, mais c'est une question intéressante pour C – shodanex

Répondre

25

POSIX printf() prend en charge les arguments de position.

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

Cool! Je n'en avais aucune idée! Toute référence? –

+0

@Amigable: 'man 3p printf' –

+0

Oh. Mais je dois dire que je ne comprends pas complètement la page de manuel. Comment peut printf ("% * d", width, num); et printf ("% 2 $ * 1 $ d", largeur, num); être équivalent si les arguments sont numérotés de gauche à droite? –

11

boost.format supporte cette manière comme dans le python mais cela est C++

+1

boost :: format est le meilleur moyen car il est également de type sécurisé. La mise en œuvre n'est pas optimisée, cependant, et appelle à printf sous les couvertures (ou a fait la dernière fois que j'ai regardé) est donc plus lent qu'en utilisant C printf directement par un facteur de 2-3. – dajames

9

Vous souhaitez l'extension% n $ s commune à la plupart des systèmes Unix.

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

Voir l'exemple allemand au bas printf

Cordialement DaveF

+0

wow - poster plusieurs secondes plus tard, c'est la différence entre 6 votes et 0. –

+0

@David Allan Finch: J'ai voté pour l'équité. Mais ça m'arrive tout le temps;) – ereOn

+0

@ereOn: pas vraiment un whinge vraiment, juste un choc que le premier post, même de quelques secondes, compte tellement pour obtenir maintenant 11 vs 2 pour la même réponse. –

23

Je ne veux pas être le porteur de mauvaises nouvelles, mais ce que vous proposez est en fait une mauvaise idée. Je travaille pour une entreprise qui prend l'i18n très au sérieux et nous avons découvert (douloureusement) que vous ne pouvez pas insérer des mots dans des phrases comme ça, car elles n'ont souvent aucun sens. Ce que nous faisons est simplement de déconnecter le texte d'erreur des bits variables afin d'éviter ces problèmes. Pour, par exemple, nous générerons une erreur:

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

Et puis, dans la description de l'erreur, vous déclarez simplement que les deux valeurs entre parenthèses à la fin étaient l'identifiant Frobozz et le nombre de zorkmids vous avez essayé de l'infliger.

Cela laisse la traduction i18n comme une tâche incroyablement facile puisque vous avez, au moment de la traduction, tous des éléments de langage dont vous avez besoin sans se soucier si les bits variables doivent être au singulier ou au pluriel, masculin ou féminin, premier, deuxième, ou troisième déclinaison (peu importe ce que cela signifie réellement).

L'équipe de traduction doit simplement convertir "Frobozz not configured for multiple zorkmids" et c'est beaucoup plus facile.


Pour ceux qui voudraient voir un exemple concret, j'ai quelque chose de nos BOD de traduction (avec suffisamment de choses a changé pour protéger les coupables).

À un certain moment, quelqu'un présenté les observations suivantes:

The {name} {object} is invalid 

{name} était le nom d'un objet (clients, commandes, etc.) et {object} était le type d'objet lui-même (table, fichier, document, stocké procédure, etc).

Assez simple pour l'anglais, la langue principale (probablement seulement) des développeurs, mais ils ont rencontré un problème lors de la traduction en allemand/suisse-allemand. Alors que le "document clients" a été traduit correctement (dans un sens positionnel) en Kundendokument, le fait que la chaîne de format ait un espace entre les deux mots était un problème. C'était essentiellement parce que les développeurs essayaient de faire paraître la phrase plus naturelle mais, malheureusement, seulement plus naturelle basée sur leur expérience limitée.

Un plus gros problème était avec la "procédure stockée des clients" qui est devenue gespeichertes Verfahren der Kunden, littéralement "procédure stockée des clients". Alors que les clients allemands peuvent avoir mis en place un espace dans Kunden dokument, il n'y a aucun moyen d'imposer gespeichertes Verfahren der Kunden sur {name} {object} avec succès.

Maintenant vous pouvez dire qu'une chaîne de format intelligent aurait fixé cela, mais il y a plusieurs raisons pour lesquelles ce serait incorrect:

  • Ceci est un exemple très simple, il y a probablement d'autres plus complexes (J'essaierais d'obtenir quelques exemples, mais nos comités de traduction ont clairement indiqué qu'ils ont un travail plus pressant que de se soumettre à tous mes caprices).
  • le point entier des chaînes de format est d'externaliser la traduction. Si les chaînes de format elles-mêmes sont spécifiques à la cible de traduction, vous avez gagné très peu en externalisant le texte.
  • les développeurs ne devraient pas avoir à se préoccuper des chaînes de format comme {possible-pre-adjectives} {possible-pre-owner} {object} {possible-post-adjectives} {possible-post-owner} {possible-postowner-adjectives}. C'est le travail des équipes de traduction car ils comprennent les nuances.

Notez que l'introduction de la déconnexion élude cette question bien:

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

Cette dernière traduction a été l'un de mes, s'il vous plaît ne pas l'utiliser pour contester la qualité de nos traducteurs. Il ne fait aucun doute que les Allemands qui parlent couramment vont bien rigoler.

+0

+1 pour les bons conseils. Je ne peux pas décider ici. Je vais cependant essayer de leur expliquer votre point de vue. – ereOn

+0

@paxdiablo: Je serais intéressé par un exemple du monde réel puisque je ne peux pas penser à un cas où cela ne fonctionnerait pas (donné des mots/identifiants significatifs à insérer dans la phrase). J'ai effectivement écrit un logiciel de cette façon, donc si vous pouvez signaler les inconvénients de la méthode, s'il vous plaît faire. –

+2

@Konrad Rudolph: Toute situation où un objet grammatical se divise en deux dans une langue mais pas dans une autre. Considérons par exemple 'printf (" je sais "," je ne sais pas "); ne sais pas ". Le négatif ne correspondra pas au modèle qui fonctionne bien pour l'anglais. – JeremyP