[C] Stocker une valeur entière dans un char * [Résolu]

Stocker une valeur entière dans un char * [Résolu] [C] - C - Programmation

Marsh Posté le 14-04-2005 à 19:32:02    

Bonjour :hello:,
 
je voudrais stocker un int dans un char *, et, par la suite, pouvoir récupérer cette valeur entière. Il faudrait que cela soit possible pour n'importe quelle valeur entière (dans les limites du type int), et que quelle que soit la valeur, sa représentation dans le char * soit contenue dans 4 octets.
 
Voili voilou, alors ça fait pas très long comme explication, mais là comme ça je vois pas trop quoi rajouter :miam:.
 
Et je sais bien que c'est un objectif stupide et sans intéret :sweat: ... mais je n'ai pas le choix :cry:.
 
Donc si vous avez des idées ou des questions, je suis preneur :whistle:.
 
Merci d'avance :jap:


Message édité par HannibAlBundy le 21-04-2005 à 01:15:10
Reply

Marsh Posté le 14-04-2005 à 19:32:02   

Reply

Marsh Posté le 14-04-2005 à 19:34:34    

utilise sprintf.
 
mais à te lire, tu voudrais plutôt faire
 
char *c;
 
c = (char*) 4;

Reply

Marsh Posté le 14-04-2005 à 20:10:35    

Taz a écrit :

utilise sprintf.
 
mais à te lire, tu voudrais plutôt faire
 
char *c;
 
c = (char*) 4;


 
Hannibal => stocker un "int" dans un "char *" ça a l'air bien étrange comme besoin. Tu veux pas nous en dire plus ? Est-ce que ta question ne serait pas plutôt "comment stocker la représentation d'un nombre dans une chaîne de caractères" ? => sprintf


Message édité par Sve@r le 14-04-2005 à 20:11:48
Reply

Marsh Posté le 14-04-2005 à 20:14:56    

Merci de l'intérêt que vous portez à mon pb :jap:.
 

Taz a écrit :

utilise sprintf.
 
mais à te lire, tu voudrais plutôt faire
 
char *c;
 
c = (char*) 4;


Si j'utilise un sprintf(c, "%d", 100000), la valeur entière 100000 ne sera-t-elle pas représentée dans la string c avec un caractère pour chaque digit, soit un total de 6 octets ?
 
Le c = (char *)4 me parait plus viable, mais j'ai bien peur encore une fois ne pas pouvoir m'assurer que quelque soit la valeur entière assignée (4 ou 100000), sa représentation dans la string c soit sur 4 octets ?
De plus, pardonnes mon faible niveaux, mais la récupération de la valeur entière 4 à partir de la string c ne me parait pas triviale :gratgrat:.
 

Sve@r a écrit :

Hannibal => stocker un "int" dans un "char *" ça a l'air bien étrange comme besoin. Tu veux pas nous en dire plus ? Est-ce que ta question ne serait pas plutôt "comment stocker la représentation d'un nombre dans une chaîne de caractères" ? => sprintf


Je sais bien que mon besoin est vraiment spécial, voir ridicule :whistle: (je l'ai d'ailleurs précisé dans mon post initial :p ), mais malheureusement c'est bien la valeur d'un int que je voudrais pouvoir stocker dans un char *, tout en m'assurant que ce stockage se fasse sur 4 octets et que je puisse récupérer cette valeur entière à partir de mon char *.
En fait, pour être plus précis, j'ai un char * dans lequel il faut que je stocke plusieurs valeur de différents types (des int, des char, des double, etc ...) et, à chaque fois, je veux que la valeur soit stockée sur un nombre d'octets correspondant au type initial, et je veux pouvoir la récupérer.
Mais le char * à la rigueur je peux peut-être m'en dispenser, selon les solutions alternatives qu'on pourrait me proposer.
 
 
Si je n'ai pas été assez clair, n'hésitez pas à me poser d'autres questions.
 
J'attend votre réponse ou celle d'autres personnes avec impatience :hello:.


Message édité par HannibAlBundy le 14-04-2005 à 20:23:57
Reply

Marsh Posté le 14-04-2005 à 20:34:06    

Dans ce cas, si c est ton char * (en supposant que tu as alloue l'espace suffisant, c'est-a-dire sizeof (int)) et i ton int : *((int *)c) = i;
 
Et pour relire l'int: i = *((int *)c);
 
Bref il suffit de caster c en (int *) avant de le derefencer. Apres, tout ce passe comme si c'etait un int *.


Message édité par matafan le 14-04-2005 à 20:34:42
Reply

Marsh Posté le 14-04-2005 à 20:49:46    

HannibAlBundy a écrit :

je voudrais stocker un int dans un char *,


C'est quoi un 'char *' ?
 
http://mapage.noos.fr/emdel/notes.htm#char_star
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 14-04-2005 à 21:09:58    

matafan a écrit :

Dans ce cas, si c est ton char * (en supposant que tu as alloue l'espace suffisant, c'est-a-dire sizeof (int)) et i ton int : *((int *)c) = i;
 
Et pour relire l'int: i = *((int *)c);
 
Bref il suffit de caster c en (int *) avant de le derefencer. Apres, tout ce passe comme si c'etait un int *.


Oki cool !
 
C'est exactement ça qu'il me fallait :hot:.
 
Merci beaucoup :jap:.
 
Par contre, je vais te déranger encore un peu :evil:, c'est pour combler mon ignorance en terme d'arithmétique de pointeur :ange: :
sachant que ma zone de stockage c est initialement un char *, lorsque je fait i = *((int *)c+2), le '+ 2' reste bien interprété comme une incrémentation de pointeur sur un char (donc + 2 octets) et non pas comme une incrémentation de pointeur sur entier (donc + 8 octets) ?
 
Merci d'avance, à priori c'est la dernière fois que je vous embêtes :whistle:.

Reply

Marsh Posté le 14-04-2005 à 22:02:14    

HannibAlBundy a écrit :

sachant que ma zone de stockage c est initialement un char *, lorsque je fait i = *((int *)c+2), le '+ 2' reste bien interprété comme une incrémentation de pointeur sur un char (donc + 2 octets) et non pas comme une incrémentation de pointeur sur entier (donc + 8 octets) ?


c est casté en (int*), donc le +2 fait 2 * sizeof (int)
 
Tu veux peut être

i = *((int *)(c+2))


soit :  

  • (c + 2) : un déplacement en char
  • (int *)(c + 2) : qui devient un pointeur sur int
  • *((int *)(c + 2)) : la valeur pointée.

Nota, cette manip n'est pas portable, notamment en raison des risques de mauvais alignement qui peut être fatal (Bus ERRor) sur certaines architectures... Tu as vraiment besoin de faire ça ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 14-04-2005 à 23:34:03    

Emmanuel Delahaye a écrit :

c est casté en (int*), donc le +2 fait 2 * sizeof (int)
 
Tu veux peut être

i = *((int *)(c+2))


soit :  

  • (c + 2) : un déplacement en char
  • (int *)(c + 2) : qui devient un pointeur sur int
  • *((int *)(c + 2)) : la valeur pointée.

Nota, cette manip n'est pas portable, notamment en raison des risques de mauvais alignement qui peut être fatal (Bus ERRor) sur certaines architectures... Tu as vraiment besoin de faire ça ?


Merci :jap:.
 
Malheureusement, je crois bien en avoir besoin :(. Seulement, ce sont uniquement mes pauvres connaissances en C qui me le font penser :sweat:. Il y a sûrement un moyen beaucoup plus simple pour stocker des valeurs de différents types dans un tableau (ou en tout cas une structure qui en a le fonctionnement), tout en contrôlant la place que prend chacune des valeurs, et en autorisant un parcours par octet (arithmétique des pointeurs ou assimilé).
 
En tout cas, merci à tous pour votre aide :hello:.

Reply

Marsh Posté le 15-04-2005 à 08:12:39    

HannibAlBundy a écrit :

Il y a sûrement un moyen beaucoup plus simple pour stocker des valeurs de différents types dans un tableau


Le mot magique est 'union'.


Message édité par Emmanuel Delahaye le 15-04-2005 à 08:13:11

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-04-2005 à 08:12:39   

Reply

Marsh Posté le 15-04-2005 à 19:27:14    

HannibAlBundy a écrit :

Merci :jap:.
Il y a sûrement un moyen beaucoup plus simple pour stocker des valeurs de différents types dans un tableau (ou en tout cas une structure qui en a le fonctionnement), tout en contrôlant la place que prend chacune des valeurs, et en autorisant un parcours par octet (arithmétique des pointeurs ou assimilé).


 
J'ai l'impression que tu veux stocker "n" éléments différents dans un tableau de "n" éléments. J'espère que j'ai bien compris ce que tu veux faire.
Cela se fait en 2 temps
1) tu crées ton type permettant de faire cela

Code :
  1. typedef union {
  2.     char carac;
  3.     int entier;
  4.     double dbl;
  5. }t_monType;


 
A partir de là, tu as à ta disposition une structure de type "t_monType" de la taille du type interne le plus large => double. Tu peux créer une variable de ce type "t_monType maVar;"
 
Cela veut dire que les zones "carac", "entier" et "dbl" de "maVar" se superposent => tu peux utiliser chacune des zones individuellement mais pas en même temps parce que si tu remplis "maVar.carac='a'" puis "maVar.dbl=3.14" tu écraseras "maVar.carac"
 
2) tu crées un tableau taille fixe ou tu alloues une zone de "n" variables de type "t_monType"

Code :
  1. t_monType tableau[10];


 
Ensuite, tu n'as plus qu'à remplir la variable que tu veux avec ce que tu veux

Code :
  1. tableau[x].carac='a';
  2. tableau[y].dbl=3.14;


 
Ensuite, faut bien que tu trouves un moyen de mémoriser qu'à la position "x" tu as un caractère et à la position "y" tu as un double... tu peux utiliser un tableau parallèle (pas terrible) ou créer une structure contenant le type + sa description

Code :
  1. typedef struct {
  2.     union {
  3.         char carac;
  4.         int entier;
  5.         double dbl;
  6.     } valeur;
  7.     int description;
  8. }t_monType;


 
Le nombre que tu mets dans "tableau[y].description" étant un nombre particulier signifiant que tu places un double dans "tableau[y].valeur.dbl".
 
Sinon une autre solution serait que tu utilises un tableau contenant un pointeur universel "void *" et une valeur descriptive de l'élément que tu stockes, chaque pointeur allant ensuite pointer vers l'élément que tu veux stocker =>

Code :
  1. typedef struct {
  2.     void *elem;
  3.     int description;
  4. }t_monType;
  5. t_monType tableau[10];
  6. tableau[x].elem=(char*)malloc(sizeof(char));
  7. *((char*)tableau[x].elem)='a';
  8. tableau[x].description=1;
  9. ...
  10. tableau[y].elem=(double *)malloc(sizeof(double));
  11. *((double*)tableau[y].elem)=3.14;
  12. tableau[y].description=2;


 
sans oublier de libérer les espaces alloués

Code :
  1. for (i=0; i < 10; i++)
  2.    free(tableau[i].elem);


 
Voilà. Bienvenue dans le monde merveilleux du C => Tu crées tes outils avant de les utiliser !


Message édité par Sve@r le 15-04-2005 à 19:28:24

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 15-04-2005 à 21:44:24    

Merci à Emmanuel Delahaye et à Sve@r pour votre dévouement :jap:, mais malheureusement (et c'est surtout malheureux pour Sve@r qui c'est démené comme un beau diable pour moi :() la solution de l'union, et du stockage de structure en général, ne peut me convenir.
En effet, désolé de pas avoir été plus clair là dessus, il m'est indispensable que chaque valeur soit stockée dans mon tableau sur le nombre d'octets correspondant à celui qu'occupe la variable dans son type initial.
Ainsi, un char doit être stocké dans mon tableau sur 1 octet, un int sur 4 octets, un double sur 8, etc ... Or, comme l'a expliqué Sve@r, avec une union, la place que prendra ma valeur est égale  à la taille du type interne le plus large. Ce type de problème sera également présent dans le cadre d'une utilisation de structure avec un void * élément et une description puisque, même si *(élément) aura la même taille que la variable originale, le tableau contiendra des structures qui ne répondront pas à mes critères de place mémoire.
 
Je pense donc que je vais resté sur la solution de matafan :ange:.
 
En tout cas re-merci pour le temps que vous me consacrez :), et puis maintenant j'ai un beau tuto sur la collection de valeurs de différent type :love:.

Reply

Marsh Posté le 16-04-2005 à 00:21:53    

HannibAlBundy a écrit :

Merci à Emmanuel Delahaye et à Sve@r pour votre dévouement :jap:, mais malheureusement (et c'est surtout malheureux pour Sve@r qui c'est démené comme un beau diable pour moi :()

Oui, je me suis éclaté là-dessus...
 

HannibAlBundy a écrit :

la solution de l'union, et du stockage de structure en général, ne peut me convenir.
En effet, désolé de pas avoir été plus clair là dessus, il m'est indispensable que chaque valeur soit stockée dans mon tableau sur le nombre d'octets correspondant à celui qu'occupe la variable dans son type initial.
Ainsi, un char doit être stocké dans mon tableau sur 1 octet, un int sur 4 octets, un double sur 8, etc ... Or, comme l'a expliqué Sve@r, avec une union, la place que prendra ma valeur est égale  à la taille du type interne le plus large.

Exact, chaque élément aura la taille d'un double (plus la taille du "int description" )
 

HannibAlBundy a écrit :

Ce type de problème sera également présent dans le cadre d'une utilisation de structure avec un void * élément et une description puisque, même si *(élément) aura la même taille que la variable originale, le tableau contiendra des structures qui ne répondront pas à mes critères de place mémoire.

Encore exact, chaque élément aura la taille d'une adresse (int) + la taille du "int description"
 

HannibAlBundy a écrit :

Je pense donc que je vais resté sur la solution de matafan :ange:.
 
En tout cas re-merci pour le temps que vous me consacrez :), et puis maintenant j'ai un beau tuto sur la collection de valeurs de différent type :love:.


 
T'as totalement le droit de faire comme t'as envie :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed