Donner des valeurs à Argc et Argv dans le code

Donner des valeurs à Argc et Argv dans le code - C - Programmation

Marsh Posté le 16-06-2006 à 11:03:14    

Bonjour,
 
Alors je m'explique, j'ai récupérer un programme qui permet de faire du POST en passant en ligne de commande l'url et les paramètre :
exemple : ./Appli URL param1=1 param2=13 ...
 
Le code code main commence donc évidement comme suit :
 

Code :
  1. int main(int argc, char** argv)
  2. {
  3.   ...
  4. }


 
Voici ce que je souhaite faire :
 
En fait le but et de faire appel à la fonction qui fait le post, sans la modifier (je veut la laiser tel que je l'ai trouvé, mis à part le fait de changer son nom en "post" à la place de "main" ). Le but et de lui passer les paramètres en dure depuis mon programme principale au lieu de lancer manuellement la fonction en ligne de commande et tapper les paramètres.
 
Exemple :
 

Code :
  1. int main ()
  2. {
  3.   int argc;
  4.   char **argv;
  5.   char *url;
  6.   char *param1;
  7.   char *param2;
  8.   //Ici le code de mon programme principale  
  9.   // Préparation des paramètres à envoyer à la fonction post  
  10.   param1="Num=22\0";
  11.   param2="Dossier=22025\0";
  12.   argv[0]="Appli\0";
  13.   argv[1]=url;
  14.   argv[2]=param1;
  15.   argv[3]=param2;
  16.   // appel de la fonction post post(argc, argv):
  17.   return 0;
  18. }
  19. //fonction qui fait le post (celle que j'ai récupéré)
  20. int post(int argc, char** argv)
  21. {
  22.   ...
  23. }


 
Hors ca ne marche pas, les paramètres sont bien transmis de mon main à la fonction post, mais la fonction plante par la suite. (erreur de segmentation)
 
 
Je suppose que je ne passe pas les parmètres comme il le faut. pourtant quand je les print dans la fonction post, ils ont l'air d'être bienb passé. Mais bon je sais qu'il est tjs délicat de toucher aux tableaux de pointer. Ou est l'erreur?
 
Un petit coup de main ne ma ferait pas de mal.
Merci d'avance !


Message édité par Vilo5 le 16-06-2006 à 11:08:33
Reply

Marsh Posté le 16-06-2006 à 11:03:14   

Reply

Marsh Posté le 16-06-2006 à 11:05:24    

Reply

Marsh Posté le 16-06-2006 à 11:21:13    


 
Ok d'accord.
Mais j'arrive pas a utiliser malloc.
 
Serait t'il possible de m'écrire le code avec malloc(), pour que je comprenne comment ca marche. Désolé je suis débutant. J'essaye d'utiliser malloc mais je n'y arrive pas.
 
Merci de ton aide !

Reply

Marsh Posté le 16-06-2006 à 11:23:25    

ben tu mettrais quoi pour malloc ?

Reply

Marsh Posté le 16-06-2006 à 11:24:57    

argv[0] = malloc( strlen("ta_chaine" ) + 1 )
strcpy(argv[0],"ta chaine" )

Reply

Marsh Posté le 16-06-2006 à 11:26:09    

pas besoin de malloc
 

Code :
  1. char * argv[ARGC];
  2. int argc = ARGC;
  3. char param1[]="Num=22";
  4. ...
  5. argv[1] = param1;
  6. ...
  7. argv[argc] = NULL;

Reply

Marsh Posté le 16-06-2006 à 11:27:50    

LePhasme a écrit :

argv[0] = malloc( strlen("ta_chaine" ) + 1 )
strcpy(argv[0],"ta chaine" )


il manque des choses là :o

Reply

Marsh Posté le 16-06-2006 à 11:32:45    

vous avez finis de faire des malloc pour copier des chaines litterales ?

Reply

Marsh Posté le 16-06-2006 à 11:34:05    

LePhasme a écrit :

argv[0] = malloc( strlen("ta_chaine" ) + 1 )
strcpy(argv[0],"ta chaine" )


 
Hmm, ton exemple est trompeur pour un débutant. Et il manque le test de l'allocation mémoire.
 
Une page à lire :  
http://mapage.noos.fr/emdel/notes.htm#pointeurs
 

Reply

Marsh Posté le 16-06-2006 à 11:35:05    

skelter a écrit :

vous avez finis de faire des malloc pour copier des chaines litterales ?


 
url, param1 et param2 sont des char* (non initialisés, ok, mais bon, à priori elles sont pas littérales ces chaînes :o )
 
Et puis, bon, j'trouve il manque un "const" pour faire bonne mesure, dans ton code [:moule_bite]

Message cité 1 fois
Message édité par Elmoricq le 16-06-2006 à 11:36:33
Reply

Marsh Posté le 16-06-2006 à 11:35:05   

Reply

Marsh Posté le 16-06-2006 à 11:40:42    

Elmoricq a écrit :

url, param1 et param2 sont des char* (non initialisés, ok, mais bon, à priori elles sont pas littérales ces chaînes :o )


 

Citation :


Le but et de lui passer les paramètres en dure depuis mon programme


 

Elmoricq a écrit :


Et puis, bon, j'trouve il manque un "const" pour faire bonne mesure, dans ton code [:moule_bite]


 
oui, 'const int argc = ARGC' c'est toujours mieux

Reply

Marsh Posté le 16-06-2006 à 11:44:03    

skelter a écrit :

Citation :


Le but et de lui passer les paramètres en dure depuis mon programme



 
Ah, ouais, j'avais pas fait gaffe à ça.
Mais dans ce cas, pourquoi il n'utilise pas int main(int argc, char **argv) comme prototype, et passer directement ces paramètres à sa fonction ? :??:
 
 
 

skelter a écrit :

oui, 'const int argc = ARGC' c'est toujours mieux


J'parlais des chaînes, pour éviter de se manger des coredumps en voulant les modifier sans faire gaffe dans le code  
[:smiley du chat qui fait la gueule]

Reply

Marsh Posté le 16-06-2006 à 11:51:36    

Elmoricq a écrit :


 
J'parlais des chaînes, pour éviter de se manger des coredumps en voulant les modifier sans faire gaffe dans le code  
[:smiley du chat qui fait la gueule]


 
?
 
char param1[]="Num=22";
 
"Num=22" est de fait un tableau constant, mais il est copié dans le tableau param1 et celui la je ne peux pas le specifier const dans la mesure ou sa fonction post a ce prototype
 
int post(int argc, char** argv)
 
parcontre il faut bien faire
 
const char * param1 = "Num=22"; (tu confondais peut etre avec ca ?)

Reply

Marsh Posté le 16-06-2006 à 11:54:01    

skelter a écrit :

?
 
char param1[]="Num=22";


 
Là ouais, mais tu avais écrit :
char *argv[ARGC];
 
Et donc là, si on fait argv[0] = "machin", et qu'on modifie argv[0][0], ça segfault
 
EDIT : ah mince, non, j'ai encore mal lu ce que tu avais écrit (tu avais fort justement assigné à argv[0] un char[]).. c'est dur pour moi ce matin [:pingouino]
mes excuses  :sweat:

Message cité 1 fois
Message édité par Elmoricq le 16-06-2006 à 11:56:47
Reply

Marsh Posté le 16-06-2006 à 11:54:28    

Oulà, je crois que je vais relire tout cà plusieurs fois et faire des essais.
 
Car là c'est pas encore très claire avec tout ces exemples.
 
Mais merci bcp de votre aide.

Reply

Marsh Posté le 16-06-2006 à 11:59:33    

Elmoricq a écrit :


Et donc là, si on fait argv[0] = "machin", et qu'on modifie argv[0][0], ça segfault


 
exact, mais 'char *argv[ARGC];' est "imposé" donc faut faire attention en initialisant les elements, avec l'adresse de tableaux modifiables

Reply

Marsh Posté le 16-06-2006 à 12:37:47    

Magnifique....
 
main() (enfin ici post()), ça vous dit qq chose ?


Message édité par el muchacho le 16-06-2006 à 12:38:58

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 16-06-2006 à 12:42:16    

Faut distinguer deux choses : le problème à résoudre dans le fond, et le code posté.
Ceci dit la solution a déjà été évoquée [:dao]

Reply

Marsh Posté le 16-06-2006 à 13:59:51    

Ok un grand merci à tous le monde.
 
Ca marche avec çà :

Code :
  1. argv[0] =(char *) malloc( strlen("chaine0" ) + 1 );
  2. strcpy(argv[0],"chaine0" );
  3. argv[1] =(char *) malloc( strlen("chaine1" ) + 1 );
  4. strcpy(argv[1],"chaine1" );
  5. argv[2] =(char *) malloc( strlen("chaine2" ) + 1 );
  6. strcpy(argv[2],"chaine2" );
  7. argv[3] =(char *) malloc( strlen("chaine3" ) + 1 );
  8. strcpy(argv[3],"chaine3" );
  9. post(argc,argv);

Reply

Marsh Posté le 16-06-2006 à 14:08:01    

il faut aussi argv[argc] == NULL

Reply

Marsh Posté le 16-06-2006 à 14:08:43    

* Le cast est inutile.
 
* argc et argv sont traditionnellement réservés aux arguments passés au programme, il peut être trompeur d'en faire des variables usuelles. Ce serait pas mal d'en changer le nom.

Reply

Marsh Posté le 16-06-2006 à 14:31:38    

skelter a écrit :

il faut aussi argv[argc] == NULL


 
Pourquoi? Moi j'ai mis argc=4 et ca passe.
Toi tu veut dire que je ferais mieux de mettre argc=5 et de faire argv[argc] == NULL.
C'est çà que tu veut dire ?
 
Si c'est çà, oui ca marche aussi. Mais quel est vraiment l'intérêt. De finir proprement mon tableau argv ?
 

Elmoricq a écrit :

* Le cast est inutile.


Comment ca le cast ???
 

Elmoricq a écrit :

* argc et argv sont traditionnellement réservés aux arguments passés au programme, il peut être trompeur d'en faire des variables usuelles. Ce serait pas mal d'en changer le nom.


Changer les noms oui ok, c'est vrai que ca serait mieux.

Message cité 2 fois
Message édité par Vilo5 le 16-06-2006 à 14:33:01
Reply

Marsh Posté le 16-06-2006 à 14:34:34    

Vilo5 a écrit :

Comment ca le cast ???


 
cast == forcer un type à la place d'un autre.
 
malloc() retourne un objet de type void*, et tu le cast en char*.  
C'est inutile, en C on n'a pas besoin de cast les objets de type void*. Du coup tu peux enlever les casts, ce qui allège quand même pas mal la lecture.

Reply

Marsh Posté le 16-06-2006 à 14:39:00    

Elmoricq a écrit :

cast == forcer un type à la place d'un autre.
 
malloc() retourne un objet de type void*, et tu le cast en char*.  
C'est inutile, en C on n'a pas besoin de cast les objets de type void*. Du coup tu peux enlever les casts, ce qui allège quand même pas mal la lecture.


 
 
Non si j'enlève les cast ca ne marche plus, j'ai mis les (char *) justement parceque sinon le compilateur gueuler parceque j'essayer de mettre du void* dans du char *.
 
Le cast est donc nécessaire.

Reply

Marsh Posté le 16-06-2006 à 14:40:41    

Non. Si tu as des erreurs, c'est que tu compiles avec un compilateur C++.

Reply

Marsh Posté le 16-06-2006 à 14:54:41    

Vilo5 a écrit :

Pourquoi? Moi j'ai mis argc=4 et ca passe.
Toi tu veut dire que je ferais mieux de mettre argc=5 et de faire argv[argc] == NULL.
C'est çà que tu veut dire ?
 
Si c'est çà, oui ca marche aussi. Mais quel est vraiment l'intérêt. De finir proprement mon tableau argv ?


 
parce que si
 
int main(int argc, char * argv[])
 
alors argv[argc] == NULL par definition, tu dois respecter ca si tu construis toi meme le tableau argv que tu passe a la fonction post, d'ailleur la taille de argv doit etre argc+1

Reply

Marsh Posté le 16-06-2006 à 14:56:16    

Elmoricq a écrit :

Non. Si tu as des erreurs, c'est que tu compiles avec un compilateur C++.


 
comme d'hab quoi :D

Reply

Marsh Posté le 16-06-2006 à 15:52:18    

Ok c'est fort possible qua ca vienne de là, j'ai compilé avec g++ car après faut que j'insère ca dans un code en c++.

Reply

Marsh Posté le 16-06-2006 à 15:57:14    

meme si tu dois interfacer ce code avec du C++ tu peux quand meme le compiler avec un compilateur C (du meme fournisseur que le compilateur C++, gcc si g++).

Reply

Marsh Posté le 16-06-2006 à 15:57:19    

Vilo5 a écrit :

Ok c'est fort possible qua ca vienne de là, j'ai compilé avec g++ car après faut que j'insère ca dans un code en c++.


 
[:pingouino]  
 
Soit tu codes en C, soit tu codes en C++. Mais surement pas les deux en même temps.
 
Tu peux écrire une bibliothèque en C, la compiler en C, et l'utiliser avec du code C++.
 
Mais on n'écrit pas du C pour le compiler avec un compilateur C++, et on greffe encore moins des fonctions C dans du code C++.
 
Parce que sinon ça donne ce qu'on appelle communément du "C/C++", c'est-à-dire un ignoble amalgame, souvent pas maintenable, incohérent, que l'on croise trop souvent à mon goût.


Message édité par Elmoricq le 16-06-2006 à 15:57:42
Reply

Marsh Posté le 16-06-2006 à 16:30:58    

Pourquoi quand je met argc=4  mon code plante, alors que quand j'omet de mettre une valeur ca se passe très bien.
 
càd que je déclare bien argc : int argc;
puis à la fin du code je fais post(argc,argv);
 
 
Mais si je met argc=4 entre tps, alors ca plante. (idem avec 3 ou 5)

Message cité 1 fois
Message édité par Vilo5 le 16-06-2006 à 16:31:52
Reply

Marsh Posté le 16-06-2006 à 19:19:39    

Vilo5 a écrit :

Ok un grand merci à tous le monde.
 
Ca marche avec çà :

Code :
  1. int main ()
  2. {
  3.   int argc;
  4.   char **argv;
  5.   argv[0] =(char *) malloc( strlen("chaine0" ) + 1 );
  6.   strcpy(argv[0],"chaine0" );
  7.   argv[1] =(char *) malloc( strlen("chaine1" ) + 1 );
  8.   strcpy(argv[1],"chaine1" );
  9.   argv[2] =(char *) malloc( strlen("chaine2" ) + 1 );
  10.   strcpy(argv[2],"chaine2" );
  11.   argv[3] =(char *) malloc( strlen("chaine3" ) + 1 );
  12.   strcpy(argv[3],"chaine3" );
  13.    post(argc,argv);



 
Bon, t'as oublié le "return 0" à la fin du main mais c'est pas ça le plus important.
Tu as un "char **" non initialisé et tu vas allègrement remplir argv[0], argv[1], argv[2] etc... sans avoir d'abord alloué l'espace nécessaire pour stocker toutes ces adresses !!!!!!
 

Code :
  1. int main ()
  2. {
  3.   int argc;
  4.   char **argv;
  5.   // FAUT COMMENCER PAR ALLOUER argv AVANT D'ALLOUER SES ELEMENTS !!!
  6.   argv=malloc(5 * sizeof(char *));
  7.   // MAINTENANT ON PEUT REMPLIR SES ELEMENTS !!!
  8.   argv[0] =(char *) malloc( strlen("chaine0" ) + 1 );
  9.   strcpy(argv[0],"chaine0" );
  10.   argv[1] =(char *) malloc( strlen("chaine1" ) + 1 );
  11.   strcpy(argv[1],"chaine1" );
  12.   argv[2] =(char *) malloc( strlen("chaine2" ) + 1 );
  13.   strcpy(argv[2],"chaine2" );
  14.   argv[3] =(char *) malloc( strlen("chaine3" ) + 1 );
  15.   strcpy(argv[3],"chaine3" );
  16.   argv[4]=NULL;
  17.    post(argc,argv);
  18.    // Faut aussi penser à libérer tous les argv[n] sauf argv[4] qui est nul
  19.    for (i=0; i < 4; i++)
  20.         free(argv[i]);
  21.    // Faut penser à libérer argv
  22.    free(argv);
  23.    return 0;
  24. }


 

Vilo5 a écrit :

Pourquoi quand je met argc=4  mon code plante, alors que quand j'omet de mettre une valeur ca se passe très bien.
 
càd que je déclare bien argc : int argc;
puis à la fin du code je fais post(argc,argv);
 
 
Mais si je met argc=4 entre tps, alors ca plante. (idem avec 3 ou 5)


C'est un comportement typique d'un pointeur non alloué dont on remplit ses adresses pointées. Ca peut sembler marcher (chance car le pointeur pointe vers une zone heureusement libre) mais un jour, on rajoute une variable, une instruction, un truc complètement anodin mais qui modifie tout le plan d'adresse mémoire de tes variables et ça marche plus. Et tu te creuse la tête pour comprendre le pourquoi du comment.
 
Règle de base: chaque fois que tu as un pointeur, style "<type> *pt", il ne faut JAMAIS aller toucher à "*pt" (ou "pt[x]" ) si on n'a pas fait auparavant "pt=<qqchose qui te donne une adresse valide>" (en général c'est "pt=malloc(...)" mais ça peut être autre chose)
Et si tu as un pointeur double, style "<type> **pt", c'est pareil. D'abord on fait "pt=<adresse valide>" puis on continue avec "pt[0]=<adresse valide>", puis "pt[1]=<adresse valide>" etc etc avant de pouvoir enfin toucher à "**pt" (ou bien "pt[x][y]" ).
Et la règle reste la même quel que soit le niveau initial de ton pointeur. Si tu as un pointeur avec 4 indirections (style "<type ****>pt", il faut commencer par remplir "pt", puis "pt[x]", puis "pt[x][y]", puis "pt[x][y][z]" avant de commencer à travailler avec "pt[x][y][z][t]"...
 
 


Message édité par Sve@r le 16-06-2006 à 19:30:28

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

Marsh Posté le 16-06-2006 à 20:35:05    

il doit manquer 'argc = 4;' dans ton code

Reply

Marsh Posté le 17-06-2006 à 03:25:08    

Elmoricq a écrit :

Faut distinguer deux choses : le problème à résoudre dans le fond, et le code posté.
Ceci dit la solution a déjà été évoquée [:dao]


Non, mais nimporte quoi [:pingouino]
Explique-moi l'intérêt de conserver argc, argv si on ne veut pas passer de params à main.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 17-06-2006 à 09:23:06    

el muchacho a écrit :

Non, mais nimporte quoi [:pingouino]
Explique-moi l'intérêt de conserver argc, argv si on ne veut pas passer de params à main.


Il ne "conserve" pas argv ou argc (tu peux remarquer d'ailleurs que son "main()" est vide de tout paramètre). Il crée juste de façon dynamiques un tableau de chaines et il nomme ce tableau "argv". Même si ce n'est pas conseillé, il en a tout à fait le droit.
 
De même, le nom "argv" qu'on met habituellement pour recevoir les paramètres n'est qu'une convention et t'as tout à fait le droit d'en utiliser un autre si t'en as envie => style

int main(int truc, char *zorglub[])



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

Marsh Posté le 17-06-2006 à 09:35:22    

Moi quand je lis:
 
 param1="Num=22\0";
 param2="Dossier=22025\0";
 argv[0]="Appli\0";
 argv[1]=url;
 argv[2]=param1;
 argv[3]=param2;
 
j'appelle pas ça du dynamique. Et il précisait "Le but et de lui passer les paramètres en dure depuis mon programme principal".[:spamafote] J'en ai conclu que c'était un bête prog de test.
 

Citation :

De même, le nom "argv" qu'on met habituellement pour recevoir les paramètres n'est qu'une convention et t'as tout à fait le droit d'en utiliser un autre si t'en as envie


C'est sympa de me le rappeler mais ça fait 15 ans que je suis au courant.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 17-06-2006 à 12:51:12    

el muchacho a écrit :

Moi quand je lis:
 
 argv[0]="Appli\0";
 argv[1]=url;
 argv[2]=param1;
 argv[3]=param2;
 
j'appelle pas ça du dynamique.


Dans le source d'où est tiré l'exemple que tu cites, il y a aussi écrit "char **argv" ce qui montre une création dynamique (surtout qu'apparemment la valeur de "url" n'est pas connue à l'avance). Evidemment il ne faut pas oublier le "argv=malloc(<...> )"...

Message cité 1 fois
Message édité par Sve@r le 17-06-2006 à 12:55:56

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

Marsh Posté le 18-06-2006 à 13:39:15    

el muchacho a écrit :

Non, mais nimporte quoi [:pingouino]
Explique-moi l'intérêt de conserver argc, argv si on ne veut pas passer de params à main.


 
Je me cite :

Citation :

* argc et argv sont traditionnellement réservés aux arguments passés au programme, il peut être trompeur d'en faire des variables usuelles. Ce serait pas mal d'en changer le nom.


 
Pour moi, il a utilisé ces noms de variables mais ce ne sont clairement pas les paramètres du programme.
Bref, y a amalgame de son côté, j'préfèrerais que ça reste du sien [:petrus75]

Message cité 1 fois
Message édité par Elmoricq le 18-06-2006 à 13:39:39
Reply

Marsh Posté le 18-06-2006 à 13:59:08    

Elmoricq a écrit :

Bref, y a amalgame de son côté, j'préfèrerais que ça reste du sien [:petrus75]


Ca, c'est son problème. Lorsqu'il se relira dans 6 mois, il comprendra ce que tu veux dire  :D


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

Marsh Posté le 22-06-2006 à 14:08:54    

Sve@r a écrit :

Dans le source d'où est tiré l'exemple que tu cites, il y a aussi écrit "char **argv" ce qui montre une création dynamique (surtout qu'apparemment la valeur de "url" n'est pas connue à l'avance). Evidemment il ne faut pas oublier le "argv=malloc(<...> )"...


Mais non, c'est juste qu'il a pris sans réfléchir les params par défaut du main d'un programme en ligne de commande qu'on lui a filé. Il n'y a rien de plus à comprendre.

Message cité 1 fois
Message édité par el muchacho le 22-06-2006 à 14:11:32

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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