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 :

Allocation dynamique, strcpy et strtok


Sujet :

C

  1. #1
    Candidat au Club
    Inscrit en
    Décembre 2009
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Allocation dynamique, strcpy et strtok
    Bonjour à tous,

    J'essaye de réaliser un "shell" qui dans lequel l'utilisateur pourra taper une chaine de caractère pouvant contenir 1,2 ou/et 3 paramètres , la mise en forme devra être du type :
    <commande> espace <op1> espace <op2>
    Il pourra au choix taper une chaine de caractère contenant un seul paramètre ( ex: dreg (puis taper entrée) -> affiche tous les registres), 2 paramètres (ex : dreg <parametre> -> reg 3 affiche le registre 3) ou une commade suivi de 2 paramètres ( ex : clear <adresse_debut> <adresse_fin> )

    Au début j'avais choisi de créer 3 tableaux de caractères statiques au début de la fonction shell pour contenir, une fois le découpage de la chaine entrée par l'utilisateur réalisée, les 3 paramètres.

    Cependant j'ai eu le problème suivant : Dans la boucle du shell, si l'utilisateur tape la commande :
    dreg 3
    puis entrée
    elle fonctionne, affiche le registre 3

    puis après il tape une seconde commande
    dreg
    et bien le 3 est toujours présent en 2eme parametre (2eme tableau de char alloué statique au début et rempli lors de la premiere boucle du do while)
    Donc ca me refait dreg 3 au lieu de dreg
    ( et je ne pense pas que ça soit possible de vider un qui a été alloué statiquement)


    Pour m'affranchir de ce problème j'ai tenté de faire de l'allocation dynamique, mais je n'arrive pas a trouver l'origine de mon erreur de segmentation, en utilisant DDD, je repère que cela viens de ma fonction découpage, mais je n'en suis pas sur, puis mon gets ne marche plus ?


    Voila mon 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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
    PARTIE CONCERNEE DU FICHIER SHELL.C
     
    #ifndef _SHELL_ /* SYMBOLE = NOM DU PT H*/
    #define _SHELL_
     
    #ifdef __cplusplus
    extern "C" {
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "mips.h"
    #include "chargement_memoire.h"
    #include "relocation.h"
    #include "simulation.h"
    #include "lecture_code.h"
    #include "identification.h"
    #include "fonctions_I.h"
    #include "fonctions_J.h"
    #include "fonctions_R.h"
    #include "commandes_simulateur.h"
    #include "commandes_shell.h"
    #include "shell.h"
    #include "utils.h"
     
    /*ICI	<defines>
    	<typedefs>
    	<prototypes>
    */
     
    #ifdef __cplusplus
    }
    #endif
    #endif
     
    void shell(void)
    {
      struct MIPS mips;
      char chaine_utilisateur_shell[256]="vide";
     
      /*
      char commande[256];
      char op1[256];
      char op2[256];
      */
      int numero_commande=0;
      int cpt=0;
     
    	char * commande_shell=NULL ;
    	char * op1_shell=NULL;
          	char * op2_shell=NULL; 
    /*
       gets(chaine_utilisateur_shell);
      if (NULL==gets(chaine_utilisateur_shell))
      	printf("\n ERROR avec le gets\n");
    */
      do
        {
         	printf ("\nsim_mips$ ");
    	gets(chaine_utilisateur_shell);
     
    	commande_shell =calloc(256,sizeof(*commande_shell));
    	op1_shell =calloc(256,sizeof(*op1_shell));
          	op2_shell =calloc(256,sizeof(*op2_shell));
     
          printf("\n indicateur 6 : juste avant le gets \n ");
     
          fct_decoupage(chaine_utilisateur_shell,commande_shell,op1_shell,op2_shell);
          numero_commande=reconnaissance_commande(commande_shell);
     
          	switch(numero_commande)
    	{
     
    	case 1: /* load */
    	  printf("\n chargement en cours ...");
    	  chargement_memoire(&mips,op1_shell);
    	  printf("\n chargement reussi");
    	  break; 
     
    	case 2:/* clear */
    	  printf("\n initialisation des reg et de la mem en cours ...");
    	  fct_clear(&mips);
    	  printf("\n initialisation terminée");
    	  break; 
     
    	case 3:/* dasm */
    	  printf("\n A faire quand la simulation marche car c'est la meme fonction que la simu sauf qu'on lieu d'executer on affiche simplement ...");
    	  break; 
     
    	case 4: /* dreg */
     
     
    	   /*Affichage de tous les registres */
    	  /*Le if permet aussi de resoudre le pb des valeurs 0 et -1 */
    	  /* strtol transforme les caracteres en nombres*/
    	  if (0==strtol(op1_shell, (char **)NULL, 10) && 0!= strcmp("-1",op1_shell) &&( 0!= strcmp("0",op1_shell )))
    	     {
    	       fct_dreg(mips,-1);
    	     }
    	   /* Affichage du registre préciser seulement */
    	   else
    	     {
    	       if( 0 == strcmp("-1",op1_shell))
    		 printf("registre inexistant");
    	       else
    		 fct_dreg(mips,strtol(op1_shell, (char **)NULL, 10));
    	     }
    	   break;
    ......
    ......
     
     
     
    PARTIE CONCERNEE DU FICHIER COMMANDES_SHELL.C
     
     
    /* Fonction qui lit et decoupe ce que l'utilisateur entre en commande 
    dans le shell avec  la structure suivante : 
    <commande> <argument_1> <argument_2>
     
    Si l'utilisateur n'entre qu'une commande sans arguments, les 2 arguments seront vides
    */
     
    void fct_decoupage(char * chaine_utilisateur, char * commande, char * op1, char * op2){
     
      /* pointeur temporaire contenant les adresses des chaines de caracteres découpées qui peuvent aussi contenir NULL s'il n'y a rien dans la chaine*/
      /*Cependant un NULL dans strcpy engendre un SEG_FAULT donc on passe par des pointeurs intermédiaires */
     
      char  * temp_commande=NULL;
      char  * temp_op1=NULL;
      char  * temp_op2=NULL;
     
     
      char * separateur = { " " }; 
      printf("\n indicateur 3 : entrée dans la fct de decoupage \n");
     
      strdup(strtok(chaine_utilisateur,separateur));
      strcpy(commande,temp_commande);
     
      printf("\n indicateur 4 : premier strcpy passé \n");
     
        temp_op1 =strtok(NULL,separateur);
      strcpy(op1,temp_op1);
     
        temp_op1 =strtok(NULL,separateur);
      strcpy(op1,temp_op1);
     
        temp_op2 =strtok(NULL,separateur);
      strcpy(op2,temp_op2);
    /*  
      if ( pt_commande != NULL)
        
      if ( pt_op1 != NULL)
        strcpy(op1,pt_op1) ;
      if ( pt_op2 != NULL)
        strcpy(op2,pt_op2) ;
    */
    }
    Merci d'avance pour votre aide

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Tout d'abord, strtok est déconseillé, il modifie l'argument.

    Deuxièmement, cela n'aurait pas été plus facile de simplement vider les tableaux ?

    Il suffirait de mettre un '\0' au début de chaque tableau avant de lire la commande de l'utilisateur.

    Jc

  3. #3
    Candidat au Club
    Inscrit en
    Décembre 2009
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    ok je vais essayé de mettre "\0" dans chaque tableau, par pour strtok, je pourrai utiliser quoi à la place ?
    Et vois-tu une erreur au niveau du gets qui pourrait expliquer pourquoi il ne marche pas ?

  4. #4
    Candidat au Club
    Inscrit en
    Décembre 2009
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    J'ai réalisé ce que tu m'as dis en mettant des initialisations du type :

    commande[0]='\0';

    Et cela à résolu mon problème, c'est beaucoup plus simple que de passer par des pointeurs

    Merci pour ton aide fearyourself

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

Discussions similaires

  1. probleme d'allocation dynamique
    Par vince3320 dans le forum C
    Réponses: 10
    Dernier message: 22/04/2004, 16h27
  2. petit pbm allocation dynamique de stringGrid
    Par AnneOlga dans le forum C++Builder
    Réponses: 10
    Dernier message: 17/01/2004, 11h59
  3. Allocation dynamique de structures
    Par fr_knoxville dans le forum C
    Réponses: 8
    Dernier message: 06/05/2003, 21h59
  4. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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