Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Influence de setlocale

5 réponses
Avatar
Taurre
Bonjour =E0 tous,

J'ai r=E9cemment essay=E9 d'ex=E9cuter ce bout de code sous Windows:

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

int
main(void)
{
puts("=E9l=E9gemment trouv=E9");
return EXIT_SUCCESS;
}

Le fichier =E9tant encod=E9 en Windows-1252 et, si mes informations sont
correctes, l'encodage utilis=E9 par la console Windows =E9tant l'IBM 850,
le programme m'affiche sans surprise: =DAl=DAgemment trouv=DA. Jusque l=E0,=
je
n'ai pas de probl=E8me, les deux encodages =E9tant diff=E9rents, il est
normal que le r=E9sultat soit incorrect.

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

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

int
main(void)
{
setlocale(LC_ALL, "");
puts("=E9l=E9gemment trouv=E9");
return EXIT_SUCCESS;
}

Et, =E0 ma grande surprise, lors de l'ex=E9cution l'affichage est
correcte. J'avoue ne pas tr=E8s bien comprendre le r=F4le que joue la
fonction setlocale dans ce cas-ci... changerait-elle l'encodage
utilis=E9 par l'invite de commande? Est-ce que quelqu'un pourrait
m'=E9clairer sur ce point?

5 réponses

Avatar
Xavier Roche
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.

<http://msdn.microsoft.com/en-us/library/x99tb11d%28v=VS.100%29.aspx>

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

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

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.

<http://msdn.microsoft.com/en-us/library/x99tb11d%28v=VS.100%29.aspx>

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?
Avatar
Xavier Roche
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)
Avatar
Antoine Leca
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
Avatar
Taurre
Voilà qui répond parfaitement à ma question.
Merci infiniment pour vos réponses ;)