Ou alors avec une fonction de copie de zone mémoire.
Mais le principe est il correct : on n'est pas obligé de ranger les byte?
Version imprimable
Ou alors avec une fonction de copie de zone mémoire.
Mais le principe est il correct : on n'est pas obligé de ranger les byte?
Si la représentation mémoire est exactement celle du réseau et qu'il n'y a pas de problèmes d'alignement, ça ira.Citation:
Envoyé par seriousme
Ce n'est pas trivial et ce n'est pas portable. J'ai proposé une méthode universelle. Est-elle vraiment couteuse ? Peut être... il faut faire des mesures...
L'endianness ou ça recouvre autre chose?Citation:
la représentation mémoire
Si l'endianness du système est bien vérifiée et que la norme de transmission est respectée ça devrait être portable.Citation:
ce n'est pas portable
La largeur de la donnée, par exemple, son alignement...Citation:
Envoyé par seriousme
Du 'portable' à coups de 'si', c'est plus du portable...Citation:
Si l'endianness du système est bien vérifiée et que la norme de transmission est respectée ça devrait être portable.
Enfin, si ça t'amuse...
seriousme : C'est à cela que servent htons/htonl...
Sur une architecture Big-Endian, il arrive qu'on trouve directement des macros #define htons(x) (x), donc aucune perte de performance...
Bonjour,
voila pour un projet je doit faire une fonction qui recois un int et le retranscrit dans un fichier en une chaine de caractere. Seulement, et pour une question de portabilite il me faut connaitre l'endian de la machine sur laquelle je suis (sinon je risque une foi sur 2 de retranscrire mon entier a l'envers).
J'ai par consequent fait quelques recherches avant de tomber sur ce topic et sur ce qui suit :
seulement je ne suis pas sur de bien comprendre ce if, et etant hors de question que je me serve d'un bout de code que je ne comprend pas je viens a vous pour vous demander quelques precisions:Citation:
Code:
1
2 int x = 1; if(*(char *) & x == 1)
- nous avons donc un masque binaire, mais je m'etonne qu'il ne soit pas fait bit par bit, et surtout que l'on compare un int (sur 4 octets) a un char (sur 1 octet).
- a quoi correspond la premiere etoile juste apres le if ?
- et d'ou vient donc ce char ?
Merci de bien vouloir repondre a tout ces questions certainement tres triviales pour vous mais qui pourraient m'etre d'une grande aide.
sprintf(), fprintf()...Citation:
Envoyé par jeroim
Pas du tout. Quand c'est converti en texte, c'est auto-démerdant (au charset près, mais ASCII couvre 99% des cas). Et même si c'était en binaire (tableau de bytes), du moment que le format du fichier (ou du flux) est spécifié (généralement 'réseau', c'est à dire MSB en tête), on sait écrire du code portable indépendant de l'endiannes, à coup de tableau de unsigned char et d'opérateurs binaires &, |, >>, << etc.Citation:
Seulement, et pour une question de portabilite il me faut connaitre l'endian de la machine sur laquelle je suis (sinon je risque une foi sur 2 de retranscrire mon entier a l'envers).
Donc, faux problème.
il y a un autre moyen dynamique :
Là c'est appliqué à des ports, mais ça indique directement little ou big endian...
ça m'a été très utile pour faire communiquer des machines Unix(HPUX, Silicon Graphics Mips) et des Linux... car :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 typedef union { int i ; char carac[4] ; }TestStruct ; test.i = 123 ; if ( test.carac[0] == '{' ){ /* network byte order. * We change to host byte order * and return the value. */ return (ntohs(isp->s_port)) ; } else{ /* host byte order. * We simply returns the value. */ return (isp->s_port) ; }
Code:
1
2
3
4
5
6
7 * On Linux machine getservbyname * returns the port in network order while on unix * machine it is not clear. Therefore we performe a test to check * the byte order for the local machine. * if the machine is is network byte order we use the * function ntohs (network to host) the change it.
Un autre ? A part la valeur de "i", quelle différence fondamentale avec ce que j'avais donné ici ?Citation:
Envoyé par souviron34
Tout d'abbord merci pour vos reponses,
en fait je ne peu me servir que de write();Citation:
Envoyé par Emmanuel Delahaye
voici ce que j'ai pour le moment, et on m'a genttilment indique que ca ne marcherai pas :
voila, moi ca me semblait tres simple comme vous pouvez le voir et j'ai eu un tres beau : "oui mais tu ne gere pas les differents endian comme ca" ...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 /* les valeurs dans l'int sont en hexadecimal, */ /* les calculs sont donc fait dans cette base */ void put_to_file(t_list_hexa *h, char *name) { char *str; int fd; /* ouverture du fichier et application des droits */ fd = open(name, O_CREAT | O_RDWR | O_TRUNC, 0760); if (fd < 0) /* verification de la valeur de retour de open */ { write(1, "Cannot open file\n", 18); exit(-1); } while (h != NULL) /* les donnees sont dans l'int hex dans cette liste chainee */ { str = xmalloc(sizeof(char) * 2); str = put_to_char(h, str); write(fd, str, 2); free(str); h = h->next; /* incrementation de la liste chainee */ } close(fd); } /* on ecrit dans le char * les caracteres un par un */ char *put_to_char(t_list_hexa *h, char *str) { if (h->hex < 10) { str[0] = '0'; str[1] = put_to_char_sub(h->hex, str[1]); } else { str[1] = put_to_char_sub(h->hex % 10, str[1]); str[0] = put_to_char_sub(h->hex / 10, str[0]); } return (str); } char put_to_char_sub(int hex, char str) { if (hex < a) str = hex + 30; /* on ajoute ce qu'il faut pour arriver */ else str = hex + 57; /* a la valeur ascii du caractere hexa */ return (str); }
ok désolé j'avais mal lu.. à cause du gros free en rouge !! :lol:
Et bien j'ai finalement compris ce fameux if qui permet de recuperer l'endian de la machine (une bonne nuit de sommeil de temps a autres fait du bien aux neurones ^^)
je vais desormais regarder pour m'en servir a bon escient, merci encore, bonne continuation.
Alors il faut cesser de parler de portabilité.Citation:
Envoyé par jeroim
Ceci n'a aucun sens. Dans une variable il n'y a que des 0 ou des 1. C'est du binaire. Point.Citation:
voici ce que j'ai pour le moment, et on m'a genttilment indique que ca ne marcherai pas :
Code:/* les valeurs dans l'int sont en hexadecimal, */
What ? Quels calculs ?Citation:
Code:/* les calculs sont donc fait dans cette base */
Ca sert à quoi d'allouer dynamiquement une tableau de taille fixe ? A m'énerver ? Accessoirement, sizeof(char) vaut 1. Toujours. (Normal, c'est l'unité de compte)Citation:
Code:str = xmalloc(sizeof(char) * 2);
"Combien y'a d'euros dans un euro ? Ben un, pourquoi ? "
Alors dans un char, y'a un char. Voilà. Logique basique...
Va falloir qu'on m'explique à quoi sert cette fonction et surtout pourquoi elle modifie str...Citation:
Code:str = put_to_char(h, str);
Ah ça vient ...
Ouch ! Tout ça pour faire une conversion num/texte en hexadécimal ? Tu devrais réfléchir au fait que les données sont codées en binaire et qu'il suffit de les traiter par groupe de 4 bits pour déterminer quelle valeur comprise entre 0 et F (0-15) on a. C'est très simple, et il n'y a aucun problème de portabilité dû à l'endianess.Citation:
/* on ecrit dans le char * les caracteres un par un */
Je propose :
int num2hex(char *s, int width, unsigned data);
qui s'utilise comme ça :
a toi de coder la fonction. Je suggère que la chaine construite soit valide, c'est à dire terminée par un 0, ça peut aider au debug (printf)Code:
1
2
3
4
5
6
7
8
9 char chaine [10]; /* a l'aise */ unsigned donnee = 128; /* 0-255 soit 00 a FF d'ou une largeur de 2 */ int largeur = 2; int err = num2hex (chaine, largeur, donnee); if (!err) { /* OK */
Avec 128, on doit obtenir "80".
Il n'y a pas ce problème avec ce que tu veux faire. Tu perds ton temps...Citation:
Envoyé par jeroim