IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

affectation dans une variable d'un argument passé au programme


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut affectation dans une variable d'un argument passé au programme
    J'ai un programma prog.exe qui nécessite des arguments pour son lancement. (prog.exe 30)
    Ces arguments sont des nombres.

    Je souhaite rajouter un argument qui doit être une chaine de caractères (nom du fichier à générer pour la sauvegarde des données) je voudrais lancer mon nouveau programme comme suit (prog.exe mon_fichier 30)

    Actuellement, mon code ressemble a ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    double gradient_chauff = 600.0;
     
    int main(int argc, char* argv[])
    {
    	// Lecture arguments
    	int i = 1;
    	gradient_chauff = atof(argv[i++]);
    Et pour rajouter l'argument souhaité, je le modifie comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    char nom_echantillon[50] = "SansNom" ;
    double gradient_chauff = 600.0;
     
    int main(int argc, char* argv[])
    {
    	// Lecture arguments
    	int i = 1;
    	nom_echantillon = (argv[i++]);
    	gradient_chauff = atof(argv[i++]);
    Bien entendu, je me fais jeter lors de la compilation !
    Je suis assez persuadé que c'est une histoire de pointeur, mais suis incapable de m'en sortir, même en ayant lu pas mal de chose.

  2. #2
    Membre chevronné

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Par défaut
    Bonjour, en C pour copier une chaine de caractères dans une autre il faut utiliser la fonction strcpy (cf duckduckgo ou qwant.com) et non pas une affectation.....

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Pour être précis, nom_echantillon est un tableau, qui ne peut pas du tout être affecté, tandis que argv[i++] est un char *, un pointeur de caractère.
    on peut remplir nom_echantillon avec les premiers caractères trouvés en partant de celui qui est pointé, mais il faut le faire assez intelligemment.

    Comme argv contient des données arbitraires venant de l'utilisateur, celles-ci ne sont pas limité à une taille arbitraire (comme le 50).
    Je recommande donc de recourir à strncpy, qui ne copie qu'un certain nombre de caractères, et dont la documentation se trouve par exemple dans la partie C de cppreference.com

  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par ternel Voir le message
    Je recommande donc de recourir à strncpy, qui ne copie qu'un certain nombre de caractères, et dont la documentation se trouve par exemple dans la partie C de cppreference.com
    Attention : strncpy n'est pas une version défensive de strcpy et peut produire un résultat qui n'est pas une chaîne de caractères C. On peut toutefois s'en servir comme telle sous réserve de comprendre le comportement de la fonction dans ses moindres détails. Je le reformule encore une fois : strncpy n'est pas à strcpy ce que snprintf est à sprintf.

    L'approche défensive de la copie de chaînes est implémentée par strlcpy (non standard).

  5. #5
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut
    Dois je écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char nom_echantillon[] = "SansNom" ;
    double gradient_chauff = 600.0;
     
    int main(int argc, char* argv[])
    {
    	// Lecture arguments
    	int i = 1;
    	strncpy (nom_echantillon, (argv[i++], 30);
    	gradient_chauff = atof(argv[i++]);
    Je n'y comprend absolument rien ! Je ne peux pas exploiter la documentation, c'est totalement incompréhensible pour moi et les exemple donnés ne me parle pas.

  6. #6
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Et je te rassure, c'est tout-à-fait normal lorsque l'on débute. C'est aussi parce que tu essaies de mettre la charrue avant les bœufs : relis la première partie du cours de C et les exercices de base sur les chaînes de caractères, posément.

  7. #7
    Membre chevronné

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Par défaut
    cela serait plutot deja cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char nom_echantillon[31] = "SansNom" ;
    double gradient_chauff = 600.0;
     
    int main(int argc, char* argv[])
    {
    	// Lecture arguments
    	int i = 1;
    	strncpy (nom_echantillon, (argv[i++], 30);
    	gradient_chauff = atof(argv[i++]);
    si tu veux copier 30 caracteres dans nom_echantillon.de plus n'oublie pas de mettre un au debut du fichier C

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 9
    Par défaut
    Bonsoir,

    Pourquoi vouloir copier argv[1] dans une autre variable ?
    Si c'est le nom de la variable qui pose en problème, pourquoi ne pas faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *nom_echantillon = argv[1];
    Après, je ne sais pas la suite du code, mais si c'est un nom de fichier, je ne vois pas le problème.

    matt...

  9. #9
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut
    Tout d'abord merci pour votre aide.

    Citation Envoyé par stephane78l Voir le message
    cela serait plutot deja cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char nom_echantillon[31] = "SansNom" ;
    double gradient_chauff = 600.0;
     
    int main(int argc, char* argv[])
    {
    	// Lecture arguments
    	int i = 1;
    	strncpy (nom_echantillon, (argv[i++], 30);
    	gradient_chauff = atof(argv[i++]);
    si tu veux copier 30 caracteres dans nom_echantillon.de plus n'oublie pas de mettre un au debut du fichier C
    Avec ça ça marche.

    Bonsoir,

    Pourquoi vouloir copier argv[1] dans une autre variable ?
    Si c'est le nom de la variable qui pose en problème, pourquoi ne pas faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part

    char *nom_echantillon = argv[1];

    Après, je ne sais pas la suite du code, mais si c'est un nom de fichier, je ne vois pas le problème.

    matt...
    Je vais essayer avec ça !
    En fait, après j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // fabrication du nom de fichier
    		sprintf(cbuf, "FichierData.%s.%s.txt", nom_echantillon, cbufTime);
    Je ne sais pas si je l'ai déjà dit, mais le code initial n'est pas de moi. Je l'ai récupéré et souhaite l'adapter à mon usage !
    Encore une fois merci pour l'aide et les explications, même si les explications restent un peu obscures pour l'instant.

  10. #10
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut
    Oui ça fonctionne aussi avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *nom_echantillon = argv[1];

    Ce que je pense comprendre, c'est que cela enregistre le contenu de argv[1] à partir de l'adresse mémoire *nom_echantillon puis dans les cases mémoires suivantes. (30) si j'ai déclaré :
    (je dois être certain de ne pas dépasser 30, sinon c'est risqué!)

    Ensuite quand j'appelle
    ça va lire à partir de l'adresse mémoire *nom_echantillon les 30 cases mémoires et je récupère ainsi le contenu de ma variable "nom_echantillon".

    Est ce cela ou je fais erreur ?

  11. #11
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 160
    Par défaut
    déclarer la variable char *nom_echantillon va déclarer un pointeur char.

    Tu dois lire les cours sur les pointeurs mais je vais aller à l'essentiel.

    Un pointeur est une variable qui ne contient pas une valeur mais l'adresse d'une valeur.

    le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *nom_echantillon = argv[1];
    va affecter l'adresse de argv[1] à nom_echantillon.

    Les deux pointent sur le même contenu, les données ne sont pas copiés mais accessibles depuis deux pointeurs différents

    https://c.developpez.com/faq/?page=L...qu-un-pointeur
    https://c.developpez.com/cours/
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 795
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par hary66 Voir le message
    ça va lire à partir de l'adresse mémoire *nom_echantillon les 30 cases mémoires et je récupère ainsi le contenu de ma variable "nom_echantillon".
    chrtophe t'a donné un bon résumé de ce qu'est un pointeur. De mon côté, je rajoute que le C n'a absolument aucune connaissance de la taille de ton tableau donc il ne sait pas qu'il doit récupérer 30 cases mémoires. C'est d'ailleurs pour ça qu'il ne dira absolument rien si tu t'amuses à lire ou écrire dans nom_echantillon[892]. Et c'est aussi donc pour ça que c'est à toi de t'autocontrôler en permanence car le C ne vérifie rien (mais en contrepartie tu bénéficies du traitement le plus rapide qu'il soit possible).

    Donc quand tu demandes à traiter nom_echantillon au travers d'une fonction de traitement de chaines de caractères (strcpy(), strlen(), printf("%s"), etc), ladite fonction part de l'adresse reçue et continue en séquentiel sur tout ce qui suit. Et elle ne s'arrête que quand elle rencontre un caractère de valeur '\0'.

    Fort heureusement, argv[1] étant récupéré depuis les arguments passés en paramètre, l'outil de récupération qui fait interface entre toi et l'exécution du code fait en sorte d'y rajouter un '\0' et c'est pour ça que ça fonctionne. Et il en va de même pour toute fonction de création de chaine (strcpy(), fgets(), etc).

    De ton côté, si un jour tu crées une chaine "à la mano" tu devras impérativement penser à rajouter ce '\0'.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/06/2014, 14h18
  2. Réponses: 3
    Dernier message: 06/09/2006, 09h06
  3. Affecter valeur d'un champ dans une variable
    Par Sly2k dans le forum Access
    Réponses: 3
    Dernier message: 17/08/2006, 09h43
  4. Affectation d'une variable dans un état
    Par tamerlan dans le forum Access
    Réponses: 26
    Dernier message: 04/04/2006, 09h09
  5. Réponses: 2
    Dernier message: 19/01/2006, 21h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo