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

[J'espère pas trop HS] Portabilité et carctères accentués

17 réponses
Avatar
Noé Falzon
Bonjour,

je suis en train de coder un petit logiciel en C, fonctionnant dans une
console. Je dispose de deux UNIX : un Mac sous OS X, et un Linux (Yellow
Dog) sur une autre machine.
J'ai remarqué (à mon grand dam :) ) que les caractères accentués des
sources écrites sur le premier ne passent pas quand je les lis sur le
second.
Je suppose que cela serait aussi le cas si je lisais les sources sous
Windows.

Je me demandais donc si dans le C standard, il y avait un moyen d'écrire
"universellement" un caractère donné, de sorte que chaque compilateur y
associe un code ASCII correspondant à la plateforme sur laquelle il
tourne.


Merci d'avance
Noé Falzon
--
"Je ne deteste que les bourreaux" -- Albert Camus

Pour m'écrire un mail, veuillez retirer PASDEPUB de mon adresse ;)

7 réponses

1 2
Avatar
James Kanze
"Antoine Leca" writes:

|> En , James Kanze va escriure:
|> : Anthony Fleury wrote in message
|> news:<40aca61c$0$25118$...
|> :> Le C n'assure rien (à ma connaissance) tant que l'on sort des
|> :> caractères normaux du jeu de caractère ASCII, c'est à dire de 0 à
|> :> 127.

|> : Même pas. Le C n'assure que ce que les caractères dits de base existe
|> : dans le locale "C", et que dans ce locale, ils s'encodent avec des
|> ^^^^^^^^^^^^^^^^^^
|> : valeurs positives.

|> Ailleurs aussi. Les valeurs (pour le jeu de base) ne changent jamais
|> entre les locales. C'est ce qui permet d'utiliser 'a', même si tu
|> changes de locale. Sinon, tu ne pourrais même pas utiliser cette
|> notation.

Je serais intéressé à savoir où se trouve cette garantie.
Parce que moi, aussi, je l'avais toujours supposé, mais quand on me
l'a démandé, je n'ai pas pu le trouver.

|> Ce qui n'est pas garanti, c'est que les caractères du jeu de base
|> soit imprimable...

Le problème, comme j'ai dit ailleurs, c'est que l'apparence des
caractères est déterminé par la police, et non par le programme
C. Donc, si j'utilise une police EBCDIC, or que le programme suppose
quelque chose dérivée d'ASCII, quand le programme croît sortir
un 'a', c'est un '/' qui s'affichera.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
James Kanze
"Antoine Leca" writes:

|> En ,
|> Noé Falzon va escriure:
|> > Je me demandais donc si dans le C standard, il y avait un moyen
|> > d'écrire "universellement" un caractère donné, de sorte
|> > que chaque compilateur y associe un code ASCII correspondant à
|> > la plateforme sur laquelle il tourne.

|> Oui. Il faut écrire u, suivi de 4 caractères hexa (exactement
|> 4) qui donne le code Unicode du caractère. C'est un truc
|> inventé vers 1995 pour Java, et cela fait partie des normes
|> C++:1998 et C:1999. Cela est même sensé marcher dans les
|> identificateurs.

En fait, il était dans les propositions (drafts) de la norme C++ au
moins aussi tôt que 1993. Je crois en fait que c'est une invention du
comité C++, qui a été adopté par Java et C. À la
différence près que l'adoptation par Java ne s'est pas bornée
à l'introduire dans la spécification ; c'est réelement
implémenté.

|> Cela dit, il ne faut pas se faire d'illusions: les compilateurs C ou
|> C++ répandus actuels, et particulièrement GCC, n'en ont cure
|> et ignore joyeusement cette particularité, arguant que « ils
|> n'ont pas moyen de connaître le jeu de caractère en cours ».

Je ne connais pas l'argument, mais c'est vrai qu'il y a bien peu de
compilateurs qui les acceptent.

En revanche, la norme dit explicitement que quelque chose comme :

enum Saisons
{
printemps,
u00E9tu00E9,
automne,
hiver
} ;

est légal. Indépendamment du « jeu de caractère en cours ».

|> Autrement, cela existe depuis plusieurs années, mais tu ne peux
|> pas en tirer partie en 2004. Bientôt, quand toutes les machines
|> et tous les OS travailleront en Unicode, c'est-à-dire quand tu
|> n'en auras plus besoin, tu pourra l'utiliser.

:-). C'est comme les trigraphes, en fin de compte.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
Antoine Leca
En , James Kanze va escriure:
: Même pas. Le C n'assure que ce que les caractères dits de base
: existe dans le locale "C", et que dans ce locale, ils s'encodent
: avec des valeurs positives.

Ailleurs aussi. Les valeurs (pour le jeu de base) ne changent
jamais entre les locales. C'est ce qui permet d'utiliser 'a', même
si tu changes de locale. Sinon, tu ne pourrais même pas utiliser
cette notation.



Je serais intéressé à savoir où se trouve cette garantie.


Bah, sinon à quoi servirait la notation 'a' ?


Parce que moi, aussi, je l'avais toujours supposé, mais quand on me
l'a démandé, je n'ai pas pu le trouver.


setlocale() n'a pas un effet infini. LC_CTYPE n'agit que sur certaines
propriétés, énumérées de manière exhaustive. Et les valeurs du jeu
d'exécution _de_base_ n'en font pas partie. Et il n'y a pas d'autres moyens
de changer de locale.


Ce qui n'est pas garanti, c'est que les caractères du jeu de base
soit imprimable...



Le problème, comme j'ai dit ailleurs, c'est que l'apparence des
caractères est déterminé par la police, et non par le programme
C. Donc, si j'utilise une police EBCDIC, or que le programme suppose
quelque chose dérivée d'ASCII, quand le programme croît sortir
un 'a', c'est un '/' qui s'affichera.


Il est impossible en C (dans le cadre de la norme) de passer de ASCII à
EBCDIC pendant l'exécution d'un programme: soit on est d'un côté, soit on
est de l'autre.

Cela n'interdit pas une implémentation de pouvoir gérer _alternativement_
les deux.


Antoine



Avatar
James Kanze
"Antoine Leca" writes:

|> En , James Kanze va escriure:
|> >>> : Même pas. Le C n'assure que ce que les caractères dits
|> >>> : de base existe dans le locale "C", et que dans ce locale, ils
|> >>> : s'encodent avec des valeurs positives.

|> >>> Ailleurs aussi. Les valeurs (pour le jeu de base) ne changent
|> >>> jamais entre les locales. C'est ce qui permet d'utiliser 'a',
|> >>> même si tu changes de locale. Sinon, tu ne pourrais même
|> >>> pas utiliser cette notation.

|> > Je serais intéressé à savoir où se trouve cette garantie.

|> Bah, sinon à quoi servirait la notation 'a' ?

Je me le démande:-). Sérieusement, tout ce qui touche à
l'internationalisation est moins évident qu'on n'y pense. Mais en
fait, je crois que la description des fonctions de <ctype.h> tend à
indiquer que c'était au moins l'intention.

|> > Parce que moi, aussi, je l'avais toujours supposé, mais quand
|> > on me l'a démandé, je n'ai pas pu le trouver.

|> setlocale() n'a pas un effet infini. LC_CTYPE n'agit que sur
|> certaines propriétés, énumérées de manière exhaustive.

Certes. Mais une des choses sur laquelle il agit sont les fonctions dans
<ctype.h>. Une fonction comme « islower » dépend du locale courant.

|> Et les valeurs du jeu d'exécution _de_base_ n'en font pas partie.
|> Et il n'y a pas d'autres moyens de changer de locale.

|> >>> Ce qui n'est pas garanti, c'est que les caractères du jeu de
|> >>> base soit imprimable...

|> > Le problème, comme j'ai dit ailleurs, c'est que l'apparence des
|> > caractères est déterminé par la police, et non par le
|> > programme C. Donc, si j'utilise une police EBCDIC, or que le
|> > programme suppose quelque chose dérivée d'ASCII, quand le
|> > programme croît sortir un 'a', c'est un '/' qui s'affichera.

|> Il est impossible en C (dans le cadre de la norme) de passer de
|> ASCII à EBCDIC pendant l'exécution d'un programme: soit on est
|> d'un côté, soit on est de l'autre.

Le but de ma declaration, c'était précisement de montrer les
limites de la norme. La norme peut dire tout ce qu'il veut, si je
démarre le programme dans une fenêtre dont l'encodage de la police
est EBCDIC, les caractères vont s'afficher comme s'ils étaient
EBCDIC. Si le programme a été compilé dans et pour un
environement classique ASCII, tolower() va bien renvoyer non nul, et
tout le programme va traiter le caractère comme si c'était un 'a',
mais l'utilisateur va voir un '/'.

|> Cela n'interdit pas une implémentation de pouvoir gérer
|> _alternativement_ les deux.

Et interdit ou non, en fin de compte, c'est la police d'affichage qui
décide.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
Noé Falzon
In article ,
James Kanze wrote:

Et interdit ou non, en fin de compte, c'est la police d'affichage qui
décide.



D'ailleurs, j'en profite, comment fonctionne une police ? Elle associe
des graphismes, mais à quoi, si ce n'est pas à l'encodage du texte ?

--
"Je ne deteste que les bourreaux" -- Albert Camus

Pour m'écrire un mail, veuillez retirer PASDEPUB de mon adresse ;)

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Noé Falzon wrote:

Et interdit ou non, en fin de compte, c'est la police d'affichage qui
décide.


D'ailleurs, j'en profite, comment fonctionne une police ? Elle associe
des graphismes, mais à quoi, si ce n'est pas à l'encodage du texte ?


Quel rapport avec le langage C? Le langage C manipule des valeurs comprises
entre 0 et 255. Le glyph associé dépend de la machine, du système, de la
carte vidéo ou des phases de la lune, mais certainement pas du langage C.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


Avatar
Antoine Leca
En , James Kanze va
escriure:
Certes. Mais une des choses sur laquelle il agit sont les fonctions
dans <ctype.h>. Une fonction comme « islower » dépend du locale
courant.


Voui. Mais cela ne va pas jusqu'à permettre que islower('A') retourne 1.


Il est impossible en C (dans le cadre de la norme) de passer de
ASCII à EBCDIC pendant l'exécution d'un programme: soit on est
d'un côté, soit on est de l'autre.



Le but de ma declaration, c'était précisement de montrer les
limites de la norme. La norme peut dire tout ce qu'il veut, si je
démarre le programme dans une fenêtre dont l'encodage de la police
est EBCDIC, les caractères vont s'afficher comme s'ils étaient
EBCDIC.


Oui. Et si c'est inutilisable, c'est _ta_ faute.
Et si tu entres 0xF0, espérant que le programme agisse comme si tu avais
écrit 0, et que le programme ne le fasse pas (parce que lui attends 0x30),
tu ne peux pas en accuser la norme, de son point de vue tout est comme il
faut, c'est toi qui _dois_ fournir 0x30 au lieu de 0xF0 (ou recompiler en
EBCDIC).


Et interdit ou non, en fin de compte, c'est la police d'affichage qui
décide.


Une IU, ce n'est pas _seulement_ une police d'affichage, c'est un peu plus
que cela. Et dans le paquet, il n'y a pas beaucoup de marge pour placer le
choix ASCII/EBCDIC.

Une autre chose, différente, sont les objets que manipulent un programme; et
quand il s'agit de chaînes de caractères brutes, cela peut être à peu près
n'importe quoi (sauf que pour utiliser les fonctions str*, il ne faut pas de
'' au milieu, ce qui interdit Unicode-16/32 ou PCL). Et on peut même
émettre ces flux, et donc les visualiser avec des polices différentes de
l'encodage "normal".

Cette utilisation, nonobstant, ne rentre pas dans les utilisations possibles
de <ctype.h> (ni de strcoll/strxfrm, bref de tout ce qui dépend de
LC_CTYPE). Parce que ce sont des bytes qui sont manipulés, mais ce ne sont
pas des caractères au sens de la clause 5.


Antoine



1 2