Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1582 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Passer une liste variable d'arguments en entrée/sortie

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Passer une liste variable d'arguments en entrée/sortie

n°596031
cedricbrun
Posté le 23-12-2003 à 13:01:50  profilanswer
 

Bonjour à tous  :hello:  
Voila mon problème :
Je voudrais faire une fonction ayant une liste d'arguments variables, à la manière de printf en quelque sorte
void mafonction (chaine, arg1, arg2, ....)
 
sauf qu'au contraire de printf, ma fonction doit modifier ces variables, elles doivent donc être passées par adresse.
Mais j'y arrive pas !  :sweat:  
Puisqu'un peu de code vaut mieux qu'un long discours :
Un fonction du genre de ce que je veux faire
Elle récupère deux variables, un entier et une chaine, et les remplacent par d'autres.

Code :
  1. void bidon(char *invite, ...)
  2. {
  3.     int *ptr_int;
  4.     char *ptr_char;
  5.     char *nouv = "Coucou c'est la nouvelle chaine";
  6.     int nouvage = 34;
  7.     // gestion des arguments d'un nombre variable
  8.     va_list liste;  // c'est la liste des arguments
  9.     va_start(liste, invite);
  10.     // on est sensé récupéré d'abord un entier
  11.     ptr_int = va_arg(liste, int *);
  12.     ptr_char = va_arg(liste, char *);
  13.     va_end(liste);
  14.     printf("On a récupéré : %s et %d\n", ptr_char, *ptr_int);
  15.     printf("On va essayer de les transformer" );
  16.     ptr_char = nouv;
  17.     ptr_int = &nouvage;
  18.     printf("On a récupéré : %s et %d\n", ptr_char, *ptr_int);
  19. }


L'appel de ma fonction dans le main

Code :
  1. int main(int argc, char *argv[])
  2. {
  3.     char *nom = "hello";
  4.     int age = 12;
  5.     bidon("invite proposée", &age, nom);
  6.     printf("\n La fonction a renvoyée nom=%s et age = %d \n", nom, age);
  7.     return 0;
  8. }


 
Et le resultat de l'appel, qui ne correspond pas à mes souhaits

Code :
  1. On a récupéré : hello et 12
  2. On va essayer de les transformerOn a récupéré : Coucou c'est la nouvelle chaine et 34
  3. La fonction a renvoyée nom=hello et age = 12


 
 
 
Vous voyez le problème ? vous avez des idées?  

mood
Publicité
Posté le 23-12-2003 à 13:01:50  profilanswer
 

n°596116
cedricbrun
Posté le 23-12-2003 à 15:03:52  profilanswer
 

y'a pas de fans de C dans la salle ?
 ;)

n°596156
xilebo
noone
Posté le 23-12-2003 à 15:37:45  profilanswer
 

ta fonction doit modifier les variables.
 
Effectivement printf n'est pas le bon exemple. Regarde du coté de scanf, c'est exactement ce qu'il te faut :)

n°596172
cedricbrun
Posté le 23-12-2003 à 15:55:05  profilanswer
 

Oui enfin bon..je veux pas faire le rabat-joie mais on a fait plus comprehensible que la glibc..
 
vraiment je comprends pas.
 
Une explications ?  qu'est-ce qui ne va pas dans mon code ? un exemple?

n°596212
Moktar1er
No one replies...
Posté le 23-12-2003 à 17:46:26  profilanswer
 

à l'avant dernière ligne de "bidon" essaie plutôt "*ptr_int=nouvage"...

n°596324
gilou
Modérateur
Modzilla
Posté le 23-12-2003 à 22:54:37  profilanswer
 

Tout n'etait pas passe par adresse comme il faur, et les assignations dans la fonction appellée n'etaient pas au bon niveau. Ceci fonbctionne:
 
 

Code :
  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. void bidon(char *invite, ...)
  4. {
  5.    int *ptr_int;
  6.    char **ptr_char;
  7.    char *nouv = "Coucou c'est la nouvelle chaine";
  8.    int nouvage = 34;
  9.    // gestion des arguments d'un nombre variable  
  10.    va_list liste;  // c'est la liste des arguments  
  11.    va_start(liste, invite);
  12.    // on est sensé récupéré d'abord un entier  
  13.    ptr_int = va_arg(liste, int *);
  14.    ptr_char = va_arg(liste, char **);
  15.    va_end(liste);
  16.    printf("On a récupéré : %s et %d\n", *ptr_char, *ptr_int);
  17.    printf("On va essayer de les transformer" );
  18.    *ptr_char = nouv;
  19.    *ptr_int = nouvage;
  20.    printf("On a récupéré : %s et %d\n", *ptr_char, *ptr_int);
  21. }
  22. int main(int argc, char *argv[])
  23. {
  24.    char *nom = "hello";
  25.    int age = 12;
  26.    bidon("invite proposée", &age, &nom);
  27.    printf("\n La fonction a renvoyée nom=%s et age = %d \n", nom, age);
  28.    return 0;
  29. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°597645
cedricbrun
Posté le 27-12-2003 à 19:02:30  profilanswer
 

:jap:  
 
Merci beaucoup, ct bien ça !
Bonne fêtes

n°597696
gilou
Modérateur
Modzilla
Posté le 27-12-2003 à 21:47:07  profilanswer
 

Bonnes fetes a toi aussi.
Le seul truc a voir, c'etait le niveau d'indirection.
J'ai ecrit
       int     *ptr_int;  
       char    **ptr_char;  
 
Mais
       int      *ptr_int;  
       char*    *ptr_char;  
aurait ete plus explicite.
 
A+,


Message édité par gilou le 27-12-2003 à 21:48:05

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°711843
The_chosen​_one
There can only be one !
Posté le 29-04-2004 à 14:51:24  profilanswer
 

Je sais que ce topic est un peu vieux mais j'aimerai qu'il remonte pour répondre a une de mes questions :)
 
voila, je cherchais justement comment faire pour passer un nb variable d'arguments, ça c'est bon.
mais ne sachant pas cb d'argument je vais passer, je voudrais savoir si il y a un moyen de récupérer ce nombre ?
est-ce que va_arg() revoie qq de spécial quand il n'y a plus d'arguments ?
 
ma f° doit faire le même traitement avec tous les arguments qu'on lui file, donc je pensait justement a une boucle while.
 
Si je m'exprime mal dites le moi, j'aimerais bien trouver :)

n°712399
djdie
L'heure, c'est l'heure.
Posté le 29-04-2004 à 23:40:58  profilanswer
 

Non il n'y a aucun moyen. Tu dois te débrouiller pour informer ta fonction du nombre d'arguments qui lui est passé.

mood
Publicité
Posté le 29-04-2004 à 23:40:58  profilanswer
 

n°712406
The_chosen​_one
There can only be one !
Posté le 29-04-2004 à 23:52:55  profilanswer
 

djdie a écrit :

Non il n'y a aucun moyen. Tu dois te débrouiller pour informer ta fonction du nombre d'arguments qui lui est passé.


hum ... bah oki ... c'est pas si compliqué que ça à mettre en place.
 
mais comment fait printf alors par exemple ?

n°712408
djdie
L'heure, c'est l'heure.
Posté le 29-04-2004 à 23:58:00  profilanswer
 

ben il regarde la chaine de format que tu lui donnes !

n°712409
The_chosen​_one
There can only be one !
Posté le 29-04-2004 à 23:59:48  profilanswer
 

hum... pas con ;)
bon, bah je passerai le nombre d'arg en arg :D
 
merci bcp

n°712486
cedricbrun
Posté le 30-04-2004 à 08:10:40  profilanswer
 

The_chosen_one a écrit :

hum... pas con ;)
bon, bah je passerai le nombre d'arg en arg :D
 
merci bcp


 
Bah on peut aussi imaginer que tu parcours tout tes arguments en les mettant de coté avant de les traiter, comme ça tu sais combien il y en a après ;)

n°713048
djdie
L'heure, c'est l'heure.
Posté le 30-04-2004 à 17:41:23  profilanswer
 

bah non justement, tu ne peux pas "parcourir tout tes arguments" puisque tu ne sais pas quand t'arrêter !

n°713339
The_chosen​_one
There can only be one !
Posté le 01-05-2004 à 01:44:39  profilanswer
 

ouais je supose que va_arg parcours la pile tout connement

n°713418
cedricbrun
Posté le 01-05-2004 à 12:56:14  profilanswer
 

bah je vois pas trop le probleme..
va_start()
va_arg()
va_end()
sont des macros, autrement dit le code est généré juste avant la compilation, donc a priori, si on fais une boucle va_start() ...... va_end() en incrementant un variable dedans on peut savoir combien on en a.. Il faudrait en même temps les mettre dans un tableau qui s'allouerai de manière dynamique pour les stocker car je suis pas sûr qu'on puis ensuite refaire un va_start() sans effet de bords (pour traiter les variables)

n°713611
darkoli
Le Petit Dinosaure Bleu
Posté le 01-05-2004 à 17:14:02  profilanswer
 

cedricbrun > Ce n'est pas une bonne idée je crois. :D
 
va_arg

...
If there is no next argument, or if type is not compatible with the  type  of  the  actual next  argument  (as  promoted according to the default argument promotions), random errors will occur.
...

Je viens de configurer man en français (au cas ou).

...
S'il  n'y  a  pas d'argument suivant, ou si type n'est pas compatible avec le type réel du prochain argument, des erreurs imprévisibles se produiront.
...


Message édité par darkoli le 01-05-2004 à 17:36:49
n°713806
djdie
L'heure, c'est l'heure.
Posté le 02-05-2004 à 03:05:24  profilanswer
 

Voilà, donc on peut pas savoir combien il y en a.
 

cedricbrun a écrit :

[...] je suis pas sûr qu'on puis ensuite refaire un va_start() sans effet de bords (pour traiter les variables)


Oui on peut, aucun problème. Ce qui est indéfini, c'est par exemple de quitter la fonction sans appeler va_end.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Passer une liste variable d'arguments en entrée/sortie

 

Sujets relatifs
[C++] implémentation d'une classe générique (liste chainée)récupérer une liste de connexions réseau ?
Existe-t-il une liste de tout les codes erreurs générés par MySQL?liste chainée en c ?
Griser 2 champs d'un formulaire par rapport au choix dans une liste :oGestion du flux d'entrée en C
Rediriger la sortie standart vers un XtermApplet securisee : faire passer IE en avant-plan ?
Quels sont les type d'arguments que l'on peut passer aux Store Proc? 
Plus de sujets relatifs à : [C] Passer une liste variable d'arguments en entrée/sortie


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR