Influence de setlocale

Le
Taurre
Bonjour à tous,

J'ai récemment essayé d'exécuter ce bout de code sous Windows:

#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
puts("élégemment trouvé");
return EXIT_SUCCESS;
}

Le fichier étant encodé en Windows-1252 et, si mes informations sont
correctes, l'encodage utilisé par la console Windows étant l'IBM 850,
le programme m'affiche sans surprise: ÚlÚgemment trouvÚ. Jusque là,=
je
n'ai pas de problème, les deux encodages étant différents, il est
normal que le résultat soit incorrect.

Par la suite, je modifies mon programme pour y inclure un appel à
setlocale, comme suit:

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
setlocale(LC_ALL, "");
puts("élégemment trouvé");
return EXIT_SUCCESS;
}

Et, à ma grande surprise, lors de l'exécution l'affichage est
correcte. J'avoue ne pas très bien comprendre le rôle que joue la
fonction setlocale dans ce cas-ci changerait-elle l'encodage
utilisé par l'invite de commande? Est-ce que quelqu'un pourrait
m'éclairer sur ce point?
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Xavier Roche
Le #24043821
Le 07/12/2011 20:37, Taurre a écrit :
fonction setlocale dans ce cas-ci... changerait-elle l'encodage
utilisé par l'invite de commande? Est-ce que quelqu'un pourrait
m'éclairer sur ce point?



En général, la valeur "" signifie "prendre la locale standard du
système" (sous les environnements POSIX, en général les LC_*) ; ici la
locale du système d'exploitation.


setlocale( LC_ALL, "" );
Sets the locale to the default, which is the user-default ANSI code
page obtained from the operating system.
Taurre
Le #24045381
Tout d'abord, merci pour cette réponse :)

On 7 déc, 22:25, Xavier Roche

En général, la valeur "" signifie "prendre la locale standard du
système" (sous les environnements POSIX, en général les LC_*) ; ici la
locale du système d'exploitation.


setlocale( LC_ALL, "" );
    Sets the locale to the default, which is the user-default ANSI co de
page obtained from the operating system.



En fait, j'avais compris que la fonction setlocale modifiait le
comportement de certaines fonctions standards afin de les adapter à la
localisation du système. Or, si c'est bien le cas, je ne comprends pas
de quelle manière le comportement de puts peut-être modifié de sorte
que l'affichage soit correcte. Est-ce elle qui va effectuer une
traduction Window-1252 => IBM 850 ou est-ce l'encodage utilisé par
l'invite de commande qui est modifié par l'appel à setlocale?
Xavier Roche
Le #24047331
Le 08/12/2011 10:23, Taurre a écrit :
localisation du système. Or, si c'est bien le cas, je ne comprends pas
de quelle manière le comportement de puts peut-être modifié de sorte
que l'affichage soit correcte. Est-ce elle qui va effectuer une



Non, puts, printf, etc. ne manipulent que des paquets d'octets, sans
toucher à rien.

La console (qui est la destination de stdout/stderr), elle, aura son
encodage changé, et interprétera de manière différente les octets qu'on
lui enverra.

(De même, en locale UTF-8 sous Linux, vous pouvez balancer de l'ISO sur
stdio, vous aurez juste des "?" sur la console)
Antoine Leca
Le #24049741
Taurre écrivit :
J'avoue ne pas très bien comprendre le rôle que joue la
fonction setlocale dans ce cas-ci... changerait-elle l'encodage
utilisé par l'invite de commande?



Pas tout-à-fait, d'ailleurs si tu testes tu vas voir que
GetConsoleOutputCP() retourne toujours la même chose ; ou bien que les
fonctions qui attaquent directement la console comme _cputs() ne sont
pas affectées par setlocale()...

En fait cette fonction change (subtilement) la table de transcodage
utilisée par les fonctions qui manipulent des « fichiers-consoles »
(donc stdout si tu ne rediriges pas.)

Est-ce que quelqu'un pourrait m'éclairer sur ce point?



MSDN, comme indiqué par Xavier; en particulier l'extension ".codepage".
La description est plutôt alambiquée à mon goût, mais j'y comprend que
l'effet de setlocale() peut aller au-delà de l'habituel changement des
tables de transcodage mb<->wc spéficié par LC_CTYPE...

http://xcybercloud.blogspot.com/2008/12/i18n-in-c-runtime-on-windows-platform.html
me paraît aussi une lecture intéressante, sur le chemin suivi par un
simple [w]printf...


De plus, pour faire bien compliqué, il semblerait que ce comportement
que tu as observé et qui est décrit ci-dessus, soit une nouveauté de
l'implémentation Vista (NT6+) ; avec NT4-5 ou VC<=7.1 (VS<2004), on a
pas d'effet collatéral, ou à tout le moins pas les mêmes...

D'ailleurs, le sujet semple particulièrement complexe si tu consultes
http://blogs.msdn.com/b/michkap/archive/2010/10/07/10072032.aspx et
toutes les autres pages (liées à cet article) très intéressantes que
Michael Kaplan a dédiées au sujet ; la conclusion que j'en retire est
qu'il est probable que les Normands aient pris le pouvoir dans le groupe
WinCon : faire telle chose, p'têt bien que c'est possible...


Antoine
Taurre
Le #24050451
Voilà qui répond parfaitement à ma question.
Merci infiniment pour vos réponses ;)
Publicité
Poster une réponse
Anonyme