OVH Cloud OVH Cloud

constante unsigned int

64 réponses
Avatar
Dominique Baldo
Est ce qu'il y a moyen de faire proprement et simplement la chose
suivante (et pas propre):

unsigned int c;
c=('é'+256)&255; // forçage de 'é' en unsigned int voire unsigned char.

10 réponses

1 2 3 4 5
Avatar
Eric Lévénez
Le 6/07/04 8:51, dans <40ea4ca5$0$14838$, « cedric »
a écrit :

Eric Lévénez wrote:
c = (unsigned char) 'é';



Ça ne marche pas toujours, en particulier avec un système qui utilise
l'UTF-8 comme Mac OS X.


Et dans ce cas il se passe quoi ? 'é' est de type wchar ou un truc comme
ca ?


Non, 'é' est une erreur de syntaxe, mais pas "é" qui est une chaîne de
caractères car é en UTF-8 est codé sur plusieurs octets donc plusieurs char.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.




Avatar
Antoine Leca
En , Emmanuel Delahaye va
escriure:
unsigned int c;
c=('é'+256)&255; // forçage de 'é' en unsigned int voire unsigned
char.


unsigned int c = 'é';


Marche pas: il veut un résultat entre 0 et UCHAR_MAX. Avec ta méthode (et en
supposant que 'é' se représente avec un seul byte), il risque d'obtenir
quelque chose dans l'intervalle [UINT_MAX+SCHAR_MIN, UINT_MAX]!


Antoine


Avatar
Antoine Leca
En BD1055EB.54C7%, Eric Lévénez va escriure:
Rappel : 'é' est illégal, par exemple, sur une architecture utilisant
l'UTF-8.


Euh ?

Sont racistes chez Unicode ? ;-)

Sans compter que cela marche très bien chez moi (la plateforme est Windows,
qui utilise, entre autres, UTF-8).


Maintenant, si c'est pour dire que 'é' n'est pas strictement conforme, je
suis bien d'accord. Mais cela n'a rien à voir avec UTF-8.


Antoine

Avatar
Vincent Lefevre
Dans l'article ,
Emmanuel Delahaye écrit:

In 'fr.comp.lang.c', Dominique Baldo wrote:

et j'aurais préféré un truc plus court genre (tapez pas merci ;o) ):
transpose[u'é']='e'


transpose[(unsigned) 'é'] = 'e'


J'espère que tu as assez de mémoire sur les implémentations où
l'encodage est en UTF-8. :)

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% validated (X)HTML - Acorn / RISC OS / ARM, free software, YP17,
Championnat International des Jeux Mathématiques et Logiques, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA


Avatar
Vincent Lefevre
Dans l'article <BD1055EB.54C7%,
Eric Lévénez écrit:

Le 6/07/04 9:10, dans <40ea4fee$0$306$,
« Richard Delorme » a écrit :

Rappel : en C, 'é' est de type int.


Rappel : 'é' est illégal, par exemple, sur une architecture utilisant
l'UTF-8.


Pas forcément.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% validated (X)HTML - Acorn / RISC OS / ARM, free software, YP17,
Championnat International des Jeux Mathématiques et Logiques, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA


Avatar
Antoine Leca
En , Dominique Baldo va escriure:
de plus (-100)&255=-100 (si on est en signé),


Ou +100, ou +155, ou +228...


En fait (honte sur moi), au départ je voulais faire un truc dans le
genre:

unsigned char transpose[256];
transpose['é']='e' // ce qui ne marche évidemment pas, du fait que 'é'
//est un entier négatif


Ce que je n'ai toujours pas compris dans l'histoire, c'est le pourquoi de
cette fixation sur 'é' ? Est-ce que c'est parce tu veux initialiser une
table avec les valeurs les plus courrantes en français ? En ce cas, pourquoi
ne pas avoir:

struct { char de, a; } transposage[] = {
{ 'é', 'e' }, {'à', 'a'}, /*...*/ };

et un petit bout de code qui fait l'initialisation de ton tableau transpose.


je n'étais pas certain que ce qui suit fonctionne:

transpose[(unsigned int)'é']='e';


Cela fonctionne, mais cela nécessite un tableau transpose de taille
conséquente, qui va poser des problèmes (et pour le coup, cela ne sera pas
"propre"...)

ou
transpose[(size_t)'é']='e';


Pire.


Si tu veux aller par là, déclare

char _transpose[SCHAR_MAX-SCHAR_MIN];
char *transpose = _transpose-SCHAR_MIN;

et tu peux écrire sans peur

transpose['é'] = 'e';

et ensuite

char c;
/* ... */
c = 'é';
/* ... */
transpose[c];


Maintenant, si tu veux faire un peu plus résistant (par exemple, du code à
utiliser par d'autres), au prix de plus de mémoire "gâchée", tu peux écrire:

char _transpose[UCHAR_MAX-SCHAR_MIN];
char *transpose = _transpose-SCHAR_MIN;

et alors ATTENTION, il faut initialiser les deux côtés du tableau

transpose['é'] = 'e';
transpose[(unsigned char)'é'] = 'e';

Ensuite, on peut écrire

int c;
/* ... */
c = 'é'; /* ou une fonction à toi, qui "renvoit" un char */
/* ... */
transpose[c];
/* ... */
c = getchar(); /* ou une fonction à toi,
qui "renvoit" un unsigned char */
/* ... */
transpose[c];


Antoine

Avatar
Antoine Leca
En 40e9f57f$0$23504$, Alexandre BACQUART va escriure:
Dominique Baldo wrote:

Est ce qu'il y a moyen de faire proprement et simplement la chose
suivante (et pas propre):

unsigned int c;
c=('é'+256)&255; // forçage de 'é' en unsigned int voire unsigned
char.


Pourquoi le +256 (qui ne sert à rien) ?


Peut-être parce que parfois, cela sert ? :->


Et d'ailleurs, tu peux très bien faire :

unsigned int c;
c = 'é';

Ca, c'est propre.


Si char est signé (ce qui est certainement le cas qui préoccupe Dominique),
cela va donner un résultat soit entre 0 et SCHAR_MAX, soit entre
UINT_MAX+SCHAR_MIN et UINT_MAX. M'étonnerait beaucoup que ce soit ce que
cherche Dominique...

Bien sûr, si en fait tu t'es trompé et que tu as voulu écrire

unsigned char c;

il n'y a rien à redire: c'est équivalent au transtypage de Vincent (avec les
mêmes inconvénients si les caractères peuvent être sur plusieurs bytes.)


Antoine


Avatar
Vincent Guichard
'é' est TOUJOURS un int. Simplement, dans un cas comme cela, 'é' est défini
par l'implémentation, et sera probablement en dehors de l'intervalle -128 ..
127 (et il y a pas mal de chances pour que ce soit 50089, 43459 ou
3282632704.)


A mon avis, les chances pour qu'un int vaille 3282632704 sont faibles.
norme ISO §5.2.4.2.2:
maximum value for an object of type int
INT_MAX +32767 // 215 - 1

Vincent Guichard

Avatar
Antoine Leca
En 20040706121411$, Vincent Lefevre va escriure:
Dans l'article ,
Emmanuel Delahaye écrit:
transpose[(unsigned) 'é'] = 'e'


J'espère que tu as assez de mémoire sur les implémentations où
l'encodage est en UTF-8. :)


En fait, UTF-8 est moins exigeant qu'un environnement 32 bits avec char
signé!


C>type fclc.c
#include <stdio.h>
#include <limits.h>

int main(void) {

printf("%un", (unsigned)'é');
return 0;
}

C>cc fclc.c

C>a
4294967273


Et au niveau mémoire, ce n'es pas un vrai problème, il "suffit" de deux ou
trois pages de mémoire virtuelle; ce qui va être un peu plus dur, c'est
d'expliquer au compilo que l'on a besoin pour cela de réserver 4Go d'espace
d'adressage...

Antoine :->


Avatar
Richard Delorme
Le 6/07/04 9:10, dans <40ea4fee$0$306$,


Rappel : en C, 'é' est de type int.


Rappel : 'é' est illégal, par exemple, sur une architecture utilisant
l'UTF-8.


Pourquoi ? Je suis d'accord que 'é' n'est légal que si le caractère é
existe dans dans l'ensemble étendu des caractères du source, et que cela
dépend de l'implémentation, mais il me semble justement que ce caractère
existe en UTF-8¹.
D'après la norme 6.4.4.4 #2, on doit avoir un ou plusieurs "multibyte
character" entre les "single-quote". Si é est écrit sur plusieurs bytes,
cela ne semble pas un problème.
Donc quel est le problème avec 'é' et UTF-8 ?

¹ Pour preuve je poste en UTF-8, et j'arrive à lire et écrire ce
caractère. (Si vous n'y arriver pas c'est que votre lecteur de news est
obsolète).

--
Richard


1 2 3 4 5