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 :

Copie char *argv[] dans char *tab[]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2010
    Messages : 26
    Par défaut Copie char *argv[] dans char *tab[]
    Bonsoir à tous !

    Voila, je rencontre un petit problème.
    Je souhaite copié le tableau (char *argv[]) dans un autre tableau.
    J'ai fait donc comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int i = 0;
    char *tab = NULL;
    tab = malloc(argc * sizeof(char*)); /* On alloue le tableau */
    if(tab == NULL) /* On vérifie s'il n'est pas NULL */
        exit(1);
    /* On copie dans le tableau */
    for(i = 0; i < argc; i++) 
        tab[i] = argv[i];
    printf("%s\n", tab[0]); /* Le programme plante à cette endroit */
     
    /* Libération de la mémoire */
    free(tab);
    tab = NULL; /* On met le pointeur à NULL */
    Par contre, je ne souhaite pas utiliser la fonction memcpy() pour copier mon tableau.

    Et, lorsque j'affiche une case du tableau (tab[0]), mon programme plante.
    J'avoue ne pas comprendre pourquoi.
    J'ai fait un autre code pour copier un autre tableau.
    Voila ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    int i = 0;
    char *tab[] = NULL;
    char *tab2[] = NULL;
    /* Allocation dynamique des tableaux */
    tab = malloc(argc * sizeof(char*));
    tab2 = malloc(argc *sizeof(char *));
    if(tab == NULL || tab2 == NULL) /* Vérification */
        exit(1);
     
    /* On ajoute dans le tableau les valeur Hello */
    for(i = 0; i < argc; i++)
        tab[i] = "Hello";
     
    /* On affiche les valeurs du tab[] */
    for(i = 0; i < argc; i++)
        printf("Tab : %s\n", tab[i]); /* Mon programme plante */
     
    /* On copie le tab[] dans tab2[] */
    for(i = 0; i < argc; i++) 
        tab2[i] = tab[i];
     
    /* On affiche les valeurs de tab2[] */
    for(i = 0; i < argc; i++)
        printf("Tab2 : %c\n", tab2[i]);
     
    /* Libération de la mémoire */
    free(tab);
    free(tab2);
     
    /* On met les pointeurs à NULL */
    tab = NULL;
    tab2 = NULL;
    Est-ce possible de copier un tableau de chaine de caractère ? Je me suis poser la question, s'il fallait copier aussi chaque caractère dans la case du tableau correspondant ?

    Je vous remercie d'avance de votre aide

    Cordialement,
    vegnagun

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *tab = NULL;
    tab = malloc(argc * sizeof(char*));
    Ceci doit alerter : Si dans le malloc() on a sizeof(type), alors la valeur de retour doit être du type type * .
    On devrait donc avoir char ** tab; Alors tab[0] sera un char * (au lieu d'un char !) ce qui est conforme avec le format "%s".

    Moyennant quoi, seuls les pointeurs sont copiés, pas les chaines de caractères. Il faut donc s'assurer de la pérennité de ces chaines pendant l'utilisation de ces adresses (si cela vient des arguments de main(), pas de problème)

    Sur le deuxième code, je suis surpris que cela compile sans erreurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char *tab[] = NULL;  
    char *tab2[] = NULL;
    /* Allocation dynamique des tableaux */
    tab = ....
    tab2 = ...

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2010
    Messages : 26
    Par défaut
    Tout d'abord, merci de t'a réponse.

    Je ne pense pas que j'ai compris votre explication sur le malloc(). Vous voulez dire que lorsqu'on appelle un malloc(sizeof(char)), la variable sera un pointeur ?

    Ah oui... J'y avais pas penser. Mais je voit pas trop comment faire pour copier les chaines de caractère et non pas les pointeurs.

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Vous voulez dire que lorsqu'on appelle un malloc(sizeof(char)), la variable sera un pointeur ?
    La valeur renvoyée par malloc() est une adresse, donc elle doit être stockée dans un objet pointeur
    Mais je voit pas trop comment faire pour copier les chaines de caractère et non pas les pointeurs
    . Pour mettre des chaines de caractères, il faut des tableaux et copier dans les tableaux en utilisant, par exemple, strcpy(). La question est alors de choisir comment créer ces tableaux : par allocation statique, automatique ou dynamique suivant le problème à résoudre

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2010
    Messages : 26
    Par défaut
    Merci pour ton explication sur le malloc().

    Mais lorsque je fait comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcpy(tab[0], argv[0]); /* Il plante */
    J'avoue ne pas trop comprendre.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    je crois que tu ne comprends pas trop ce que signifient les symboles..

    char *argv[] est équivalent char **argv

    Quand tu références argv[0], tu pointes donc sur une chaîne.

    Vu que tu n'as pas alloué tab[0] avec la longueur de la chaîne, ça plante..

    Pour dupliquer argv, le plus simple serait :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int i ;
    char **tab;
     
    tab = malloc ( argc * sizeof(char*) );
     
    if ( tab != NULL )
      for i = 0 ; i < argc ; i++ )
         tab[i] = strdup(argv[i]) ;

  7. #7
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    argv est un tableau de chaines de caractères (un tableau de tableaux), alors argv[0] est l'adresse de début d'une chaine de caractères (voir plus bas) c'est à dire l'adresse de début d'un TABLEAU de char.

    Par contre, tab est un tableau de pointeurs et tab[0] est un pointeur. Pour qu'on puisse écrire strcpy(tab[0], argv[0]) , il faut que tab[0] contienne l'adresse de début d'un tableau de char (suffisamment grand).

    Il faut absolument faire la différence entre un pointeur et un tableau.
    Il n'y a aucune connection entre objet pointeur et tableau. Par contre, il y en a une entre adresse et tableau.
    La difficulté vient d'une mauvaise terminologie : il y a confusion entre objet pointeur (que j'appelle simplement pointeur) et constante pointeur (que j'appelle adresse) sous un seul vocable "pointeur" alors que les deux choses sont différentes. Pourtant, le principe est simple. Pour résumer :

    1- Un pointeur est un objet qui ne peut être utilisé que pour stocker une adresse (on voit que la différence entre pointeur et adresse est celle qui existe entre le conteneur et le contenu).

    2- L'identificateur A associé à un tableau ne représente l'objet tableau que dans 3 types d'expressions : sizeof A , &A et (A). Dans tous les autres cas, c'est une adresse (celle du premier élément du tableau identifié par A). Ce n'est pas, dans ces cas, un objet (donc a fortiori un objet pointeur).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. différence entre char **argv et char *argv[]
    Par BoxOfTheNight dans le forum C
    Réponses: 3
    Dernier message: 23/08/2014, 08h54
  2. copier tous les argv dans un seul char*
    Par coyotemk dans le forum Débuter
    Réponses: 3
    Dernier message: 06/12/2008, 17h14
  3. Convertir un (char *) en (const char *) dans C++
    Par anas.eh dans le forum C++
    Réponses: 10
    Dernier message: 03/09/2007, 13h59
  4. Tableau de char[] passé dans une fonction
    Par Joratois dans le forum C
    Réponses: 26
    Dernier message: 07/06/2007, 15h06
  5. char** argv incompris
    Par sanatou dans le forum C++
    Réponses: 2
    Dernier message: 07/12/2006, 11h51

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