Donner des valeurs à Argc et Argv dans le code - C - Programmation
Marsh Posté le 16-06-2006 à 11:21:13
Elmoricq a écrit : malloc() |
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 !
Marsh Posté le 16-06-2006 à 11:24:57
ReplyMarsh Posté le 16-06-2006 à 11:26:09
pas besoin de malloc
Code :
|
Marsh Posté le 16-06-2006 à 11:27:50
LePhasme a écrit : argv[0] = malloc( strlen("ta_chaine" ) + 1 ) |
il manque des choses là
Marsh Posté le 16-06-2006 à 11:32:45
ReplyMarsh Posté le 16-06-2006 à 11:34:05
LePhasme a écrit : argv[0] = malloc( strlen("ta_chaine" ) + 1 ) |
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
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 )
Et puis, bon, j'trouve il manque un "const" pour faire bonne mesure, dans ton code
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 ) |
Citation : |
Elmoricq a écrit : |
oui, 'const int argc = ARGC' c'est toujours mieux
Marsh Posté le 16-06-2006 à 11:44:03
skelter a écrit :
|
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
Marsh Posté le 16-06-2006 à 11:51:36
Elmoricq a écrit : |
?
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 ?)
Marsh Posté le 16-06-2006 à 11:54:01
skelter a écrit : ? |
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
mes excuses
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.
Marsh Posté le 16-06-2006 à 11:59:33
Elmoricq a écrit : |
exact, mais 'char *argv[ARGC];' est "imposé" donc faut faire attention en initialisant les elements, avec l'adresse de tableaux modifiables
Marsh Posté le 16-06-2006 à 12:37:47
Magnifique....
main() (enfin ici post()), ça vous dit qq chose ?
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
Marsh Posté le 16-06-2006 à 13:59:51
Ok un grand merci à tous le monde.
Ca marche avec çà :
Code :
|
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.
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.
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.
Marsh Posté le 16-06-2006 à 14:39:00
Elmoricq a écrit : cast == forcer un type à la place d'un autre. |
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.
Marsh Posté le 16-06-2006 à 14:40:41
ReplyMarsh Posté le 16-06-2006 à 14:54:41
Vilo5 a écrit : Pourquoi? Moi j'ai mis argc=4 et ca passe. |
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
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
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++.
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++).
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++. |
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.
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)
Marsh Posté le 16-06-2006 à 19:19:39
Vilo5 a écrit : Ok un grand merci à tous le monde.
|
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 :
|
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'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]"...
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é. |
Non, mais nimporte quoi
Explique-moi l'intérêt de conserver argc, argv si on ne veut pas passer de params à main.
Marsh Posté le 17-06-2006 à 09:23:06
el muchacho a écrit : Non, mais nimporte quoi |
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[]) |
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". 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.
Marsh Posté le 17-06-2006 à 12:51:12
el muchacho a écrit : Moi quand je lis: |
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(<...> )"...
Marsh Posté le 18-06-2006 à 13:39:15
el muchacho a écrit : Non, mais nimporte quoi |
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
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 |
Ca, c'est son problème. Lorsqu'il se relira dans 6 mois, il comprendra ce que tu veux dire
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.
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 :
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 :
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