OVH Cloud OVH Cloud

conversion codage local vers ascii

63 réponses
Avatar
cedric
Une question simple et bête pour changer un peut de la taille des void*:

J'ai un programme qui parse des entêtes de mails, donc, de l'ASCII.
Par exemple, je cherche le caractère ascii du signe égual dans un
buffer. Or, rien ne me dit que je peu chercher le caractère C '=' car a
priori l'encodage local n'est pas nécessairement de l'ASCII. Le
programme cherche donc la valeur numérique de ce caractère (61).

Je me demande si toutes ces précautions ne sont pas exagérées, d'autant
qu'elles alourdissent le programme (surtout lorsqu'il faut chercher des
chaînes de caractères, case insensitive, l'horreur!).

Bref, connaissez vous beaucoup d'architectures encore vivantes qui
utilisent un autre encodage que l'ASCII et sur lesquelles tournent des
serveurs de mails ? Sinon, je remplace tout ça par des belles strings C
et je pourrai utiliser strcmp et consorts...

10 réponses

3 4 5 6 7
Avatar
James Kanze
"Charlie Gordon" writes:

|> "James Kanze" wrote in message
|> news:
|> > "Antoine Leca" writes:

|> > |> En ,
|> > |> James Kanze va escriure:
|> > |> [ toascii() ]
|> > |> >>> > et qui ... fait un and binaire avec 127 ! arf arf, rien
|> > |> >>> > à voir avec une conversion ascii...

|> > |> > En fait, ça date d'une époque où la mémoire était sévérement
|> > |> > limitée, et les machines très lentes.

|> > |> ... et les lignes téléphoniques très mauvaises, donc tout le
|> > |> traffic était encodé sur 7 bits plus un bit de parité. Sur une
|> > |> bécane qui recevait le traffic dans un octet, le bit de parité
|> > |> se retrouvait automatiquement dans le poids fort. toascii() le
|> > |> faisait disparaître.

|> > Sauf que sur les machines où j'ai réelement vu tosacii, le
|> > masquage du bit de parité se faisait dans les couches basses du
|> > pilote du contrôleur séries, et les programmes utilisateurs ne le
|> > voyaient jamais. Et que s'ils le voyaient, c'est ou bien que le
|> > SIO était mal programmé (et qu'ils devaient en tenir compte aussi
|> > dans des choses comme strcmp, ce qui n'était pas le cas), ou bien,
|> > plus souvent, que l'utilisateur avait rédirigé les entrées depuis
|> > un fichier binaire (et que la meilleure chose à faire aurait été
|> > de détecter que les entrées étaient foirées, et s'en aller
|> > proprement avec un message d'erreur).

|> C était le langage d'implémentation d'unix et de ses drivers, où
|> l'utilisation de macros comme toascii() était loisible, même si la
|> plupart de la libc (stdio) était inutilisable dans ce contexte

Dans ce cas-là, il me semble que je suis en train de travailler au
niveau des bits, et non des encodages. Donc, quelque chose comme c &
0x7F me semble bien plus lisible.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
Jean-Marc
"James Kanze" a écrit dans le message de
news:
"Charlie Gordon" writes:

|> "James Kanze" wrote in message
|> news:
|> > "Antoine Leca" writes:

|> C était le langage d'implémentation d'unix et de ses drivers, où
|> l'utilisation de macros comme toascii() était loisible, même si la
|> plupart de la libc (stdio) était inutilisable dans ce contexte

Dans ce cas-là, il me semble que je suis en train de travailler au
niveau des bits, et non des encodages. Donc, quelque chose comme c &
0x7F me semble bien plus lisible.


Hello,

je rejoins cette idée. Un code bien écrit devrait toujours laisser
apparaitre l'intention du programmeur. Dans ce contexte, un toascii()
ne me dit rien (ou même me dit des choses fausses) alors qu'un c & Ox7F
est immédiatement parlant: on comprend à la lecture "ah ok, il annule
le 8ème bit, il se ramene à 0-127". Bien entendu, on suppose que dans le
code complet on aurait en plus un commentaire adéquat comme par exemple:

/* remove parity bit */
c = c & 0x7F;

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."

Avatar
Emmanuel Delahaye
Jean-Marc wrote on 13/11/04 :
/* remove parity bit */
c = c & 0x7F;


euh comme ça, c'est encore lisible ?

/* remove parity bit */
c &= ~0x80;

parce qu'on fait du C quand même...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Avatar
Jean-Marc
"Emmanuel Delahaye" a écrit dans le message de
news:
Jean-Marc wrote on 13/11/04 :
/* remove parity bit */
c = c & 0x7F;


euh comme ça, c'est encore lisible ?

/* remove parity bit */
c &= ~0x80;


Oui, c'est encore lisible.

parce qu'on fait du C quand même...


Oui, ce qui ne veut pas dire qu'on cherche systématiquement à gagner le
coucours d'obfuscation de code, en particulier dans du code de
production, mais bon. Affaire de style, pas affaire de C.

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."


Avatar
Eric Lévénez
Le 13/11/04 19:42, dans ,
« Emmanuel Delahaye » a écrit :

Jean-Marc wrote on 13/11/04 :
/* remove parity bit */
c = c & 0x7F;


euh comme ça, c'est encore lisible ?

/* remove parity bit */
c &= ~0x80;


Il pourrait y avoir des problèmes si c fait plus de 8 bits.

Je préfère la première solution écrite :

c &= 0x7f;

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


Avatar
Emmanuel Delahaye
Eric Lévénez wrote on 13/11/04 :
Le 13/11/04 19:42, dans ,

Jean-Marc wrote on 13/11/04 :
/* remove parity bit */
c = c & 0x7F;


euh comme ça, c'est encore lisible ?

/* remove parity bit */
c &= ~0x80;


Il pourrait y avoir des problèmes si c fait plus de 8 bits.


Quels problèmes ?

Je préfère la première solution écrite :

c &= 0x7f;


Et la différence, c'est quoi ?

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"



Avatar
Charlie Gordon
"Jean-Marc" wrote in message
news:419638b8$0$19179$
"James Kanze" a écrit dans le message de
news:
"Charlie Gordon" writes:

|> "James Kanze" wrote in message
|> news:
|> > "Antoine Leca" writes:

|> C était le langage d'implémentation d'unix et de ses drivers, où
|> l'utilisation de macros comme toascii() était loisible, même si la
|> plupart de la libc (stdio) était inutilisable dans ce contexte

Dans ce cas-là, il me semble que je suis en train de travailler au
niveau des bits, et non des encodages. Donc, quelque chose comme c &
0x7F me semble bien plus lisible.


Hello,

je rejoins cette idée. Un code bien écrit devrait toujours laisser
apparaitre l'intention du programmeur. Dans ce contexte, un toascii()
ne me dit rien (ou même me dit des choses fausses) alors qu'un c & Ox7F
est immédiatement parlant: on comprend à la lecture "ah ok, il annule
le 8ème bit, il se ramene à 0-127". Bien entendu, on suppose que dans le
code complet on aurait en plus un commentaire adéquat comme par exemple:


bien que écrit comme cela, il faut quand même faire une supposition sur la
valeur de Ox7F.

#define Ox7F 0x7f /* any other value would be misleading! */

Chqrlie.


Avatar
Charlie Gordon
"Emmanuel Delahaye" wrote in message
news:
Jean-Marc wrote on 13/11/04 :
/* remove parity bit */
c = c & 0x7F;


euh comme ça, c'est encore lisible ?

/* remove parity bit */
c &= ~0x80;

parce qu'on fait du C quand même...


Un opérateur nand m'a toujours manqué dans ce langage, avec une syntaxe évidente
: ~ binaire ferait très bien l'affaire.

/* add high bit */
c |= 0x80;

/* remove high bit */
c ~= 0x80;

Mais bon, on peut vivre sans.

Chqrlie.


Avatar
Eric Lévénez
Le 13/11/04 22:58, dans ,
« Emmanuel Delahaye » a écrit :

Eric Lévénez wrote on 13/11/04 :
Le 13/11/04 19:42, dans ,

Jean-Marc wrote on 13/11/04 :
/* remove parity bit */
c = c & 0x7F;


euh comme ça, c'est encore lisible ?

/* remove parity bit */
c &= ~0x80;


Il pourrait y avoir des problèmes si c fait plus de 8 bits.


Quels problèmes ?


À cause de l'extension possible du signe, le bit de parité étant souvent
traité comme cela.

Voici un exemple avec une machine avec des chars 8 bits et des ints 32 bits.
Mais cela peut aussi être applicables avec des char 16 bits par exemple (cas
où on lit un octet sur un périphérique et qu'on le range dans un char avec
extension de signe)

#include <stdio.h>

int main(void)
{
char c = 'A';
int d, e;

// Ajout d'une parité
c |= 0x80;
d = e = c;

// Suppression de la parité
d &= ~0x80;
e &= 0x7f;

printf("Méthode 1: %#xn", d);
printf("Méthode 2: %#xn", e);
return 0;
}

Méthode 1: 0xffffff41
Méthode 2: 0x41


Je préfère la première solution écrite :

c &= 0x7f;


Et la différence, c'est quoi ?


Différence avec quoi ? Si c'est avec la première proposition, c'est juste
plus lisible à mon sens que de répéter 2 fois la variable (tout comme c++
est plus lisible que c = c + 1). Si c'est avec la seconde proposition, c'est
une expression qui marche dans tous les cas.

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




Avatar
James Kanze
"Charlie Gordon" writes:

|> "Emmanuel Delahaye" wrote in message
|> news:
|> > Jean-Marc wrote on 13/11/04 :
|> > > /* remove parity bit */
|> > > c = c & 0x7F;

|> > euh comme ça, c'est encore lisible ?

|> > /* remove parity bit */
|> > c &= ~0x80;

|> > parce qu'on fait du C quand même...

|> Un opérateur nand m'a toujours manqué dans ce langage, avec une
|> syntaxe évidente : ~ binaire ferait très bien l'affaire.

|> /* add high bit */
|> c |= 0x80;

|> /* remove high bit */
|> c ~= 0x80;

|> Mais bon, on peut vivre sans.

Tout à fait. Dans la fonction en question, en revanche, l'opération
voulue n'était pas d'enlever le bit de poids fort, mais d'enlever tous
les bits qui n'appartenaient pas au code de caractère. Le code en
question est 7 bits, donc, & 0x7F me semble convenir le plus.

Dans d'autres contextes, évidemment, & ~0x80 serait préférable.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
3 4 5 6 7