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 :

Erreur! Création d'un nouveau fichier.


Sujet :

C

  1. #1
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut Erreur! Création d'un nouveau fichier.
    Salut!
    Je suis en pleine création d'un petit programme. Je trouve un petit problème dans l'exécution. Ce dernier est destiné à indexer des fichiers, et de sauvegarder les différents mots et son nombre d'occurence dans un fichier spécifique index.txt. Aucune erreur au niveau de la compilation ni au niveau de l'exécution mais plutôt lors de la création du nouveau fichier, ce fait ne veux pas marcher d'où son affichage sur console na marche pas. Je sais ps pourquoi.

    S'il vous plaît, j'ai besoin d'une aide.

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    typedef struct link link;
    struct link
    {
        char nom[30];
        int nbOccur;    // nombre d'incrémentation de la chaîne
        link *suivant;
    };
     
    link* trouve(char CH[30], link *tete)
    {
        link *ptr = tete;
     
        while(ptr != NULL && !strcmp(ptr->nom, CH))
            ptr=ptr->suivant;
     
        return ptr;
    }
     
    link* insertQueue(char CH[30], link *tete)
    {
        link *newLink = NULL;
        link *ptr = tete;
     
        if (ptr!= NULL)
            while(ptr->suivant != NULL )
                ptr=ptr->suivant;
     
        newLink=(link*)malloc(sizeof(link));
        newLink->suivant = NULL;
        strcpy(newLink->nom, CH);
        newLink->nbOccur = 1;
     
        if (ptr!= NULL)
            {
                ptr->suivant = newLink;
                return tete;
            }
        else
            return newLink;
     
    }
     
    void createNewFile(link *tete)
    {
        FILE *fichier = NULL;
        link *ptr = tete;
     
        fichier = fopen("index.txt", "w+");
     
        if(fichier != NULL)
        {
            while(ptr != NULL)
            {
                fprintf(fichier, "%s\t\t%d\n", ptr->nom, ptr->nbOccur);
                ptr = ptr->suivant;
            }
            fclose(fichier);
        }
    }
     
    void affichNewFile()
    {
        FILE *fichier = NULL;
        int caractereActuel = 0;
     
        fichier = fopen("index.txt", "r");
     
        if(fichier != NULL)
        {
            do
            {
                caractereActuel = getc(fichier);
                printf("%c", caractereActuel);
            }
            while(caractereActuel != EOF);
        }
    }
     
    int main(int argc, char *argv[])
    {
        link *tete = NULL;              // Tête de liste
        link *mot = tete;               // parcours de la liste de chaînes
        FILE *fichier = NULL;           // Pointeur sur fichier à traîter
        int caractereActuel = 0;        // Caractère en cours de traitement
        char chaineEnCours[30] = "\0";  // Chaîne en cours de formation
        char carac[2] = " " ;           // Sert pour la convertion d'un caractère en chaîne
        char path[50];                  // Path du fichier à traîter
     
        printf("Chemin du fichier a traiter : ");
        gets(path);
     
        fichier = fopen(path, "r");
     
        if (fichier != NULL)
        {
            // Boucle de lecture des caractères un à un
            do
            {
                caractereActuel = fgetc(fichier);
     
                if(isspace(caractereActuel) || caractereActuel=='.' || caractereActuel==',' || caractereActuel==';' || caractereActuel=='?' || caractereActuel=='!' || caractereActuel==':' || strcmp(chaineEnCours, "\0"))
                {
                    mot = trouve(chaineEnCours, tete);
     
                    if(mot != NULL)
                    {
                        mot->nbOccur = mot->nbOccur + 1;
                        mot = NULL;
                    }
                    else
                        tete = insertQueue(chaineEnCours, tete);
     
                    strcpy(chaineEnCours, "\0");
                }
                else
                {
                    carac[0] = (char)caractereActuel;
                    carac[1] = '\0';
                    strcat(chaineEnCours, carac);
                }
     
            } while (caractereActuel != EOF); // On continue tant que fgetc n'a pas retourné EOF (fin de fichier)
     
            fclose(fichier);
        }
        else
            printf("Impossible d'ouvrir le fichier %s!", path);
     
        createNewFile(tete);
        affichNewFile();
     
        free(mot);
        free(tete);
     
        return 0;
    }
    D'avance, merci beaucoup!

  2. #2
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 451
    Points
    451
    Par défaut
    J'ai du mal à voir ce que tu veux faire exactement

    Mais, dès le début il y a un truc qui m'intrigue lors de ton premier appel à la fonction "trouve" à laquelle tu passes "tete" initialisé à NULL, tu initialises ptr avec tete et tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        while(ptr != NULL && !strcmp(ptr->nom, CH))
            ptr=ptr->suivant;
     
        return ptr;
    du coup, si je ne m'abuse, tu ne devrais jamais rentrer dans la boucle est renvoyer NULL, et comme après tu ne modifies pas "tete" avant de faire d'autres appels le retour de "trouve" devrait être assez souvent NULL

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insertQueue(chaineEnCours, tete);
    Tu va effectuer une copie de tete.
    Donc tête vaudra toujours NULL.

    Tu as deux solutions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tete = insertQueue(chaineEnCours, tete);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insertQueue(chaineEnCours, &tete);

    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
    void insertQueue(char CH[30], link *tete)
    {
        link *newLink = NULL;
        link *ptr = tete;
     
        if (ptr!= NULL)
            while(ptr->suivant != NULL )
                ptr=ptr->suivant;
     
        newLink=(link*)malloc(sizeof(link));
        newLink->suivant = NULL;
        strcpy(newLink->nom, CH);
        newLink->nbOcuur = 1;
     
        if (ptr!= NULL)
            ptr->suivant = newLink;
        else
            ptr = newLink;
     
        free(newLink);
    }
    Tu alloue dynamiquement un maillon et tu le libère à la fin de ta fonction.
    Soit tu n'as besoin de ton maillon uniquement dans ta fonction et tu utilise une variable locale, soit tu libère le maillon uniquement lorsque tu en aura besoin, c'est à dire, ici, à la fin de ton main juste avant ton free(tete).

  4. #4
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    D'accord, merci je viens d'éditer ma postule, mais il y a tjrs une erreur quelque part.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Enlève la fonction de free(newLink); de ta fonction insertQueue.

    Ensuite il suffira de créer une fonction de suppression qui désallouera tous tes maillons.

    Il faut bien comprendre ce que tu fais, avec malloc, tu alloue un maillon.
    Ensuite tu place toutes les valeurs dans ce maillon puis tu supprime ton maillon, quel intérêt?

    De plus tu risque à tout moment d'avoir un SEGFAULT parce que tu aura un pointeur qui pointera vers un maillon non-alloué.

  6. #6
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Pour ne pas charger la RAM avec des cases inutiles, j'ai plus besoin du NewLink du coups je l'enlève lorsque je termine d'utiliser ma fonction.

  7. #7
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    newLink est alloué automatiquement, c'est une variable locale qui sera détruite à la fermeture du bloc où il a été déclaré ie à la sortie de ta fonction.


    Par contre, le contenu pointé par newLink est alloué dynamiquement.
    free(newLink) ne va pas désaloué newLink, mais le contenu pointé par newLink.
    Or tu as besoin de ce contenu jusqu'à ce que tu détruise ta liste.

  8. #8
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Non mais, le free(newLink) ça va libérer le contenu du newLink qui est un pointeur vers une structure de type link. Ceci veut dire que ça ne va libérer que l'adresse contenu dans le newLink. Mais pas le contenu de la case qui occupe cette adresse. Sinon, pour optimiser j'affirme qu'il vaut mieux supprimer free(newLink) à cause de l'auto-destruction.

    Mais le problème est bien dans le main.

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Citation Envoyé par http://man.developpez.com/man3/free.3.php
    void free (void * ptr);

    free() libère l'espace mémoire pointé par ptr, qui a été obtenu lors d'un appel antérieur à malloc(), calloc() ou realloc(). Si le pointeur ptr n'a pas été obtenu par l'un de ces appels, ou si il a déjà été libéré avec free(), le comportement est indéterminé. Si ptr est NULL, aucune tentative de libération n'a lieu.

  10. #10
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    D'accord merci bien, sinon il y a tjrs un truc qui cloche au main.

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    tete = insertQueue(chaineEnCours, &tete);
    C'est l'un ou l'autre mais pas les deux.

    Sinon pour ta boucle de lecture, tu as beaucoup plus simple :
    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
     
    int taille = 0;
    int caractereLu = fgetc(fichier); //fgetc renvois un int, EOF est un int.
    while(caractereLu != EOF)
    {
             if(....) //si la chaine est finie
             {
                       tab[taille] = '\0';
                       taille = 0;
              }
              else
              {
                       tab[taille] = (char)caractereLu;
                      taille++;
               }
             fgetc(fichier)
     
     
    }
    Il faut aussi respecter ceci :
    lecture - vérification - traitement de la donnée lue.
    Il faut donc vérifier que tu n'es pas arrivé à la fin du fichier avant de traiter le caractère lu.
    En effet, EOF n'apparait pas quand tu lis le dernier caractère, mais quand tu essaye de lire au delà.

    Citation Envoyé par http://man.developpez.com/man3/fgets.3.php
    int fgetc (FILE *stream);

  12. #12
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    J'ai reformulé ma première solution, que j'ai publié.
    Quels sont les erreurs à ton avis, stp?

  13. #13
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Citation Envoyé par Neckara
    Il faut donc vérifier que tu n'es pas arrivé à la fin du fichier avant de traiter le caractère lu

  14. #14
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    C'est déjà fait non? Bah le problème c'est que je veux qu'il copie colle tous les mots du fichier (son nom est demandé à l'utilisateur) et leurs nombre d'occurrence dans un autre "index.txt".

    Alors que le programme que j'ai publié n'arrive pas à le faire. ^^'

  15. #15
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Citation Envoyé par Sayuri Voir le message
    C'est déjà fait non?
    Non, tu lis le caractère, tu le traite mais tu ne fais la vérification qu'à la toute fin.
    Il faut lire, vérifier et ensuite traiter.

    Je t'ai donné un exemple de code beaucoup plus simple et efficace, essaye de t'en inspirer.


    Citation Envoyé par Sayuri Voir le message
    Bah le problème c'est que je veux qu'il copie colle tous les mots du fichier (son nom est demandé à l'utilisateur) et leurs nombre d'occurrence dans un autre "index.txt".
    C'est encore plus simple alors :
    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 nbMot = 0;
    int isLastCaractereNotEspace = 0;
    while(...)
    {
            if(caractere == espacement)
            {
                    if(LastCaractere)
                              nbMot++;
                   isLastCaractereNotEspace = 0;
             }
             else
             {
                     fputc(caractere, fichierEcriture);
                     isLastCaractereNotEspace = 1;
              }
             //fgetc();
    }

  16. #16
    Futur Membre du Club
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci bien, mais j'ai opté pour une autre solution moins complexe. xD
    Celle des tableaux à une dimension.
    J'achèverai la solution où les listes chaînées représentent la structure de données.


Discussions similaires

  1. Réponses: 2
    Dernier message: 29/04/2014, 09h50
  2. Réponses: 3
    Dernier message: 16/05/2011, 21h57
  3. Compacter une BD = création d'un nouveau fichier
    Par mimir123 dans le forum Modélisation
    Réponses: 2
    Dernier message: 16/05/2008, 20h32
  4. [DOM] probléme de création d'un nouveau fichier XML
    Par nonna dans le forum Format d'échange (XML, JSON...)
    Réponses: 6
    Dernier message: 29/04/2008, 10h48
  5. Réponses: 16
    Dernier message: 04/01/2006, 14h54

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