bonjour,
Je cherche à utiliser
en ayant les messages en français.Code:fprintf(stderr,"%s\n",strerror(errno));
Si je tapes locale, j'ai la valeur :
LC_MESSAGES="fr_FR.UTF-8"
si quelqu'un peut m'expliquer, je vous en remercie d'avance.
Version imprimable
bonjour,
Je cherche à utiliser
en ayant les messages en français.Code:fprintf(stderr,"%s\n",strerror(errno));
Si je tapes locale, j'ai la valeur :
LC_MESSAGES="fr_FR.UTF-8"
si quelqu'un peut m'expliquer, je vous en remercie d'avance.
Bonjour;
deux possibilités :
- utiliser la variable d'environnement LANGUAGE :
Code:
1
2
3
4
5
6 $ls /truc ls: cannot access /truc: No such file or directory $LC_MESSAGES=fr ls /truc ls: cannot access /truc: No such file or directory $LANGUAGE=fr ls /truc ls: impossible d'accéder à /truc: Aucun fichier ou dossier de ce type
- installer le package de traduction des messages de la libc en Français. Avec ma distribution les traductions se trouvent dans /usr/share/locale/fr/LC_MESSAGES/libc.mo
EDIT:
une troisième possibilité :
- utiliser setlocale (je supposais que tu l'avais fait ...)
Un code pas trop trop popre pour l'exemple
Donne à l'exécution :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <locale.h> int main (int argc, char *argv[]) { char *loc; char *old_loc=setlocale (LC_ALL, NULL); printf ("old locale = %s\n", old_loc?old_loc:"not defined"); if ( (argc>1) && argv[1]) { if ( (loc=setlocale (LC_ALL, argv[1])) == NULL ) { printf( "'%s' not a valid locale string\n", argv[1]); } else { printf ("new locale = %s\n", loc); } } printf ("EINVAL -> %s\n", strerror(EINVAL)); return 0; }
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 $ ./err old locale = C EINVAL -> Invalid argument $ $ LANGUAGE=fr_FR.utf8 ./err old locale = C EINVAL -> Invalid argument $ $ ./err fr_FR.utf8 old locale = C new locale = fr_FR.utf8 EINVAL -> Argument invalide $ $ LANGUAGE=en ./err fr_FR.utf8 old locale = C new locale = fr_FR.utf8 EINVAL -> Invalid argument
Merci Picodev,
ça fonctionne en ajoutant ceci à mon code :
J'ai cru comprendre que cette commande prend les infos de locale du système. Pourquoi cela n'est pas fait par défaut ? mon système étant en français.Code:setlocale (LC_ALL,"");
La locale par défaut est probablement l'équivalent de setlocale (LC_ALL,"C");
Dans la doc de la glibc :
Le comportement découle de ce qui est requis par la norme POSIX.Citation:
7.4 How Programs Set the Locale
A C program inherits its locale environment variables when it starts up. This happens automatically. However, these variables do not automatically control the locale used by the library functions, because ISO C says that all programs start by default in the standard ‘C’ locale. To use the locales specified by the environment, you must call setlocale. Call it as follows:
setlocale (LC_ALL, "");
to select a locale based on the user choice of the appropriate environment variables.
You can also use setlocale to specify a particular locale, for general use or for a specific category.
Bonjour,
J'ai trouvé cette discussion intéressante et j'ai donc voulu testé tout ça. J'ai donc écrit un petit bout de C, que je compile avec GCC sous OS X.
Voici le code C :
Le problème est que le message fourni par strerror n'est jamais traduit. J'ai essayé avec es_ES et j'obtiens aussi un message en anglais. Un exemple en console :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <errno.h> #include <locale.h> #include <stdio.h> #include <string.h> int main(int argc, char **argv) { errno = 0; // Show current locale char *loc = setlocale(LC_ALL, NULL); printf("When program starts, the locale is: %s\n", loc); puts("Let's change the locale..."); // Try to change the locale and print a localized message in case of success loc = setlocale(LC_ALL, "fr_FR"); if(loc == NULL) { perror("Error: impossible to set locale properly"); } else { printf("The new locale is: %s\n", loc); printf("Checking the current locale: %s\n", setlocale(LC_ALL, NULL)); puts("The next message should be localized"); printf("%s\n", strerror(EINVAL)); } }
Avez-vous une idée de ce qui m'échappe ? : /$ ./C When program starts, the locale is: C Let's change the locale... The new locale is: fr_FR Checking the current locale: fr_FR The next message should be localized Invalid argument
Merci d'avance.
Ah, ok.Citation:
Le comportement découle de ce qui est requis par la norme POSIX.
Bktero, essayes :
Pour moi ça a réglé le prob.Code:setlocale (LC_ALL,"");
Du coup, je laisses le POST ouvert.
J'avais testé, mais sans effet.
J'ai modifié mon code pour le rendre un poil plus modulaire :
Lorsque je lance depuis Eclipse, la sortie console est :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <errno.h> #include <locale.h> #include <stdio.h> #include <string.h> int main(int argc, char **argv) { errno = 0; int category = LC_ALL; char* locale = ""; // Show current locale char *loc = setlocale(category, NULL); printf("When program starts, the locale is: %s\n", loc); puts("Let's change the locale..."); // Try to change the locale and print a localized message in case of success loc = setlocale(category, locale); if(loc == NULL) { perror("Error: impossible to set locale properly"); } else { printf("The new locale is: %s\n", loc); printf("Checking the current locale: %s\n", setlocale(category, NULL)); puts("The next message should be localized"); printf("%s\n", strerror(EINVAL)); } }
Lorsque je lance depuis le terminal bash :When program starts, the locale is: C Let's change the locale... The new locale is: C Checking the current locale: C The next message should be localized Invalid argument
Je vais finir par me demander si mes fichiers de traduction ne contiennent pas tous de l'anglais...$ ./C When program starts, the locale is: C Let's change the locale... The new locale is: fr_FR.UTF-8 Checking the current locale: fr_FR.UTF-8 The next message should be localized Invalid argument
Honnêtement non ... en fouillant un peu je pense avoir compris que la locale donnée en paramètre à setlocale doit être l'une de celles installées sur le système. Pour avoir la liste il faut lancer un locale -a qui sur mon système donne :
En réutilisant ton code et en remplaçant le fr_FR par un fr_FR.utf8 cela fonctionne.Code:
1
2
3
4
5 $ locale -a C en_US.utf8 fr_FR.utf8 POSIX
J'ai essayé de rajouter une nouvelle locale nommée fr_FR en ajoutant la ligne
dans le fichier /etc/locale.gen et en regénérant les locales avec locale-gen. locale -a me donne ensuite :Code:fr_FR UTF-8
et ton programme fonctionne tel quel.Code:
1
2
3
4
5
6 $ locale -a C en_US.utf8 fr_FR fr_FR.utf8 POSIX
D'après ce que j'ai pu lire dans les docs de gettext ce comportement serait dû à la transition vers UTF8 au début des années 2000. Depuis cette époque la forme fr_FR était un alias pour fr_FR.iso8859 et il fallait explicitement spécifier fr_FR.utf8 pour l'utf8. Cette dénomination est restée après que l'iso8859 soit tombé en désuétude. Si on ne spécifie pas utf8 alors on retombe sur la locale C qui utilise ... l'ASCII sans doute, et ce qui permet d'éviter des affichages incompréhensibles.
Mais là il faudrait approfondir et lire beaucoup de doc, voire faire de la paléo-informatique ^^.
Cette locale existe bien, j'étais allé vérifié dans les dossiers de locales. Il y a effectivement des liens, et nombreux sont ceux qui repointent vers ISO truc. locale -a me renvoie une liste bien longue de locales, et fr_FR est dedans ;)
Je viens de tester sur Windows 7 avec MinGW, j'obtiens :
Je continue de tester :pWhen program starts, the locale is: C Let's change the locale... The new locale is: French_France.1252 Checking the current locale: French_France.1252 The next message should be localized Invalid argument Process returned 0 (0x0) execution time : 0.031 s Press any key to continue.
PS : je viens de tester sur Xubuntu 14.04 (anglais) en lui demandant d'utiliser non pas "" mais "fr_FR.UTF-8" et même problème :
Vous avez installé des paquets spéciaux les gens ?./a.out When program starts, the locale is: C Let's change the locale... The new locale is: fr_FR.UTF-8 Checking the current locale: fr_FR.UTF-8 The next message should be localized Invalid argument
@bktero : Quelles sont les valeurs de tes variables d'environnement LANGUAGE, LC_ALL et LANG ?
Sur ce Xubuntu, j'ai :
Je me suis aussi aperçu que la locale était "fr_FR.utf8" et non "fr_FR.UTF-8" sur ce système, j'ai modifié le code C en accord mais pas mieux. Je vais finir par laisser tomber ^^$ locale LANG=en_US.UTF-8 LANGUAGE=en_US LC_CTYPE="en_US.UTF-8" LC_NUMERIC=fr_FR.UTF-8 LC_TIME=fr_FR.UTF-8 LC_COLLATE="en_US.UTF-8" LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES="en_US.UTF-8" LC_PAPER=fr_FR.UTF-8 LC_NAME=fr_FR.UTF-8 LC_ADDRESS=fr_FR.UTF-8 LC_TELEPHONE=fr_FR.UTF-8 LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=fr_FR.UTF-8 LC_ALL=
Je pense que tu le sais, mais Mac OS X est basé sur FreeBSD et pas sur Linux. la différence utf8/utf-8 vient peut-être de là.
Par ailleurs, t'as essayé avec xcode ou autre chose ? En plus les dernières versions utilisent LLVM. Je sais pas si ça a un impact, ça dépasse ma compétence.
a mon avis, l'un des problèmes, ce sont les guillemets dans les définitions des variables d'environnement.
Par ailleurs, certains dont LC_MESSAGES sont définis pour l'anglais.
La libc utilise gettext pour localiser ses messages. Le chemin des fichiers des traductions est construit au runtime. Il y a une partie dépendant du système, /usr/share/locale par eemple. Le reste du chemin est composé de 3 parties :
- locale
Le nom de la locale sélectionnée, par exemple fr_FR.utf8
- LC_cat
LC_MESSAGES pour les messages traduits.
- domainname
Un nom spécifique à l'application, la bibliothèque ...
La composante locale est construite en premier lieu à partir des valeurs des variables d'environnement suivantes ; LANGUAGE, LC_ALL, LC_XXX, LANG par ordre de priorité et ce quelle que soit la locale demandée par setlocale.
Comme tu as défini la variable LANGUAGE c'est elle qui aura priorité. D'ailleurs dans ton cas, la valeur de toutes les variables vont te faire pointer vers des messages en anglais. L'utilité principale de LANGUAGE semble être la possibilité d'indiquer plusieurs langues par ordre de priorité. Par exemple LANGUAGE="fr:en" cherchera en priorité des messages en Français puis s'il n'en trouve ceux en Anglais.
Tout cela provient de la doc de GNU gettext.