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 :

Problème avec la fonction realloc après un system(cls) !


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 13
    Points : 13
    Points
    13
    Par défaut Problème avec la fonction realloc après un system(cls) !
    Bonjour

    j'ai un gros souci avec le redimensionnement d'un tableau de structure, en effet lorsque j'incrémente le tableau d'une case, le redimensionnement échoue !!! en effet le tableau me renvoie des erreurs sur les enregistrements. J'explique le fonctionnement de mon programme: en gros je récupère des données nom,prénom etc... formatées dans un fichier créer au préalable puis je les insèrent dans un tableau dynamique dont la taille correspond au nombre de lignes du fichier (ou nombre d'enregistrements), j'insère ensuite un nouvel enregistrement, j'incrémente donc la taille du tableau de +1, j'agrandis donc le tableau de +1 case, le problème survient lorsque j'utilise la fonction "system("cls");" puisque j'ai essayé de mettre la fonction "realloc();" avant le system("cls") et l'ajout de l'utilisateur se fait sans aucun problème.

    Par avance Merci de votre aide !

    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
    #include<stdlib.h>
    #include<stdio.h>
    #include<conio.h>
    #include<string.h>
    #include<cctype>
     
    int TAILLE_MAX=0;
     
    typedef struct profile profile;
    struct profile
    {
    int  id;
    char nom[20];
    char prenom[30];
    char numtel[11];
    char email[20];
    };
     
    int realloc_tab(profile *tab)
    {
     
    profile *temp = NULL;//on définit ici un pointeur temp sur la structure profile
    temp = (profile *) realloc (tab,TAILLE_MAX * sizeof(profile));
    if ( temp == NULL )
    {
         fprintf(stderr,"Reallocation impossible");
         free(tab);
         exit(EXIT_FAILURE);
         return 0;
    }
    else {
         tab = temp;
         return 1;
         }
     
    }
     
    //On ajoute ici le nouvel utilisateur dans le tableau et dans le fichier
    int create_user(char nom[20], char prenom[30], char numtel[11], char email[30], profile *tab)
    {
    char ch[30];
    int i=0;
     
    i=TAILLE_MAX;//on définit la case d'ajout ici elle correspond à la TAILLE_MAX puisque le tableau commence à 0
    TAILLE_MAX++;//on incrémente la taille du tableau
    if(realloc_tab(tab)==1){
    tab[i].id=i+1;
    strcpy(tab[i].nom,strlwr(nom));
    strcpy(tab[i].prenom,strlwr(prenom));
    strcpy(tab[i].numtel,numtel);
    strcpy(tab[i].email,strlwr(email));
    return 1; } else { return 0;}
    }
     
     
    int main(void) {
    FILE *pf;
    char chaine[100],nom[20]="durand",prenom[30]="ererer",numtel[11]="0241361227",email[30]="dfdfdf",rep;
    int i=0,choix;
    profile * tab = NULL;
     
    pf = fopen("C:\\Annuaire\\test.txt","r"); 
    do
      {
        if (fgetc(pf)=='\n')
        {
        TAILLE_MAX++;
        }
    }while(!feof(pf));
    rewind(pf);
     
    tab = (profile *) malloc (TAILLE_MAX * sizeof(profile));
    if( tab == NULL )
    {
         fprintf(stderr,"Allocation impossible");
         exit(EXIT_FAILURE);
    }  
     
    if (pf != NULL)
        {
         do
           {
            fgets(chaine,100,pf);
            sscanf(chaine,"| %d | %s | %s | %s | %s |",&tab[i].id,tab[i].nom,tab[i].prenom,tab[i].numtel,tab[i].email);
            i++;
           }while(i!=TAILLE_MAX);
        }
    fclose(pf);
     
    do
    {
    system("cls");
     
    for(i=0;i<TAILLE_MAX;i++)   printf("| %d | %s | %s | %s | %s |\n",tab[i].id,tab[i].nom,tab[i].prenom,tab[i].numtel,tab[i].email);
     
    printf("\nQue voulez-vous faire ? :\n\n1-Ajouter un utilisateur\n....");
    printf("\n\nVotre choix : ");
    scanf("%d",&choix);
    printf("\n");
    switch(choix) {
                  case 1: {
                       create_user(nom,prenom,numtel,email,tab);
                       }    
                       break;
                  case 2: {
                       }
                       break;
                  case 3: {
                      }    
                       break;
     
                  default: {printf("\nErreur de saisie !!!\n\n");
                            getch(); }
     
    }
     
    }while(rep!='n' && rep!='N');
    getch();
    return 0;
    }
    puis le fichier "test.txt" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    | 1 | osiris | durand | 0136173456 | coco@hotmail.com |

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par djskynet Voir le message
    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
    int realloc_tab(profile *tab)
    {
     
    profile *temp = NULL;//on définit ici un pointeur temp sur la structure profile
    temp = (profile *) realloc (tab,TAILLE_MAX * sizeof(profile));
    if ( temp == NULL )
    {
         fprintf(stderr,"Reallocation impossible");
         free(tab);
         exit(EXIT_FAILURE);
         return 0;
    }
    else {
         tab = temp;
         return 1;
         }
     
    }
    Si la réallocation réussi, temp reçoit l'adresse de la nouvelle zone mémoire tandis que l'adresse stockée dans tab devient invalide. Comme en C, le passage des arguments se fait uniquement par valeur, l'affectation:

    ne modifie pas l'adresse correspondante dans la fonction appelante.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 13
    Points : 13
    Points
    13
    Par défaut
    Merci mais j'ai du mal à comprendre, la fonction à l'air correct non ? lorsque j'appelle la fonction faut il que je passe un deuxième paramètres "tab" c'est ça ?
    désolé mais j'ai pas très bien compris le problème.

    Par avance Merci !

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 25
    Points : 29
    Points
    29
    Par défaut
    En fait, ta fonction est (presque) correcte. Thierry a expliqué le principe, je vais essayé d'illustrer le fonctionnement

    au premier coup, tu alloues tab à une valeur "maximale". On peut donc considérer que tab pointe vers l'adresse 0x02 (attention, toutes les valeurs que je donne sont arbitraires.)

    Maintenant, tu as besoin de plus d'espace. Tu appelles donc ta fonction realloc_tab(tab);

    MAIS, tab est copié : c'est à dire que le tab que connait ta fonction n'est pas le même que celui présent dans ton main() ! Donc, ta fonction va réallouer l'espace pour son tab, et affecter à son tab la valeur temp !
    tab -> 0x02
    appel de realloc_tab
    tab est copié dans la liste des arguments de la fonction.
    tab -> 0x02
    temp -> 0x0142AF
    allocation ok, tu affectes temp à tab
    tab -> 0x0142AF
    fin de l'appel
    le tab copié est détruit.
    tab -> 0x02 (l'ancienne zone mémoire, inutilisable).

    Pour corriger cette erreur, tu as plusieurs solutions :
    - soit ton realloc_tab se comporte comme le realloc :
    Profile * realloc_tab(Profile * anc_tab);

    - soit tu vas changer la valeur, là où pointe tab :
    int realloc_tab(Profile ** tab);

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par djskynet Voir le message
    Merci mais j'ai du mal à comprendre, la fonction à l'air correct non ? lorsque j'appelle la fonction faut il que je passe un deuxième paramètres "tab" c'est ça ?
    désolé mais j'ai pas très bien compris le problème.

    Par avance Merci !
    Une fonction qui modifie une variable doit recevoir l'adresse de cette variable et doit travailler avec "* <adresse reçue>. C'est la règle de base qui s'applique tout le temps. Exemple int i; scanf("%d", &i);

    Donc toi t'as un "profile *tab" dans ta fonction principale, tu veux que realloc_tab modifie ce "tab" il te faut lui passer "&tab"
    Et ta fonction realloc reçoit cette adresse qui est de type "profile **" qu'elle stocke donc dans une variable "profile **titi". Puis elle travaillera avec "*titi". Chaque fois que "*titi" sera modifié, comme cela modifiera ce qui est pointé par titi cela ira modifier tab.
    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]

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 29/04/2008, 13h38
  2. Problème avec la fonction findfirst ()
    Par Angelico dans le forum Windows
    Réponses: 3
    Dernier message: 05/08/2004, 20h40
  3. [Requete SQL en VBA] Problème avec la fonction FLOOR
    Par zubral dans le forum Langage SQL
    Réponses: 4
    Dernier message: 13/07/2004, 13h24
  4. Problème avec les fonctions
    Par jvachez dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 13/01/2004, 12h06
  5. [Postgresql]Problème avec les fonctions ...
    Par fet dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/10/2003, 09h04

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