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 :

Lecture et sélection dans un fichier txt


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2015
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2015
    Messages : 105
    Par défaut Lecture et sélection dans un fichier txt
    Bonjour a tous,

    Beaucoup de gens m'ont aidé sur le sujet suivant mais j'ai encore quelques soucis:

    Je vais essayer d'etre très précis sur mon travail et clair sur mon objectif.

    Je veux dans un premier temps lire la totalité d'un fichier txt. Ce fichier est divisé en plusieurs gros blocs avec une multitude d'informations que je ne souhaite pas toute sélectionner mais avec des tests je détermine le commencement du bloc puis je sélectionner par des myens qui seront dans mon code.Je souhaite donc lire ce txt, déterminer le commencement du bloc, inscire les informations souhaitées dans des structures.L'identifiant de la structure sera stocké dans une table de hachage pour me permettre de créer des liens entre mes structures (chaque identifiant donc commencement de bloc de structure peut être en lien avec une autre et je souhaite créer des liens).

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    /***************************Structure applications*****************************************/
    typedef struct applications
    {
        char id     [20];
        char descr  [20];
        char owner  [20];
        char preid  [20];
    }applications;
     
     
    /**************************Nombre de ligne du txt********************************/
     
    int cpteLignes(FILE*batch){
    char ligne_lue[255];
    int nb_lignes=0;
                    while(fgets(ligne_lue, 512, batch) != NULL)
                        {
                            printf("\t%s", ligne_lue);
                            nb_lignes++;
                        }printf("le fichier comporte %d lignes\n", nb_lignes);
                        return nb_lignes;
    //                  rewind (ligne_lue);
                        fclose(batch),batch=NULL;
     
    /**************************Fonction main**************************************************/
     
    int main()
    {
    char ligne_lue[256];
    char tableau1 []= "ADSTART";
    char tableau []= "PREADID";
    struct applications tab[1000];
    int n=0;
    int i=0;
    struct applications applications = {"jean", "pierre", "paul","jack"};
     
     
    FILE*batch;
    batch=fopen("D:\\Users\\xxx\\Desktop\\xxx\\xxx\\xxx.txt","r");
     
    FILE*extract;
    extract=fopen("D:\\Users\\xxx\\Desktop\\xxx\\xxx\\xxx.txt","w");
     
    /****************************Test de lecture fichier*****************************************/
     
            if (batch==NULL)
            {
    		fputs("erreur a l'ouverture du fichier\n",stderr);
    		return EXIT_FAILURE;
            }
    /**************************Tests & Ecriture dans les structures******************************/
                n=cpteLignes;
                        for(i=0;i<n;i++)
                        {
                           fscanf(batch,"%s",&ligne_lue);
                               if(strcmp(ligne_lue,tableau1)==0)
                                {
                                    fscanf(batch,"%*[^\n]\n  %*[^(](%99[^)])", &tab[i].id);
                                    fscanf(batch,"%*[^\n]\n  %*[^(](%99[^)])", &tab[i].descr);
                                    fscanf(batch,"%*[^\n]\n  %*[^(](%99[^)])", &tab[i].owner);
                                    fscanf(batch,"%*[^\n]\n  %*[^(](%99[^)])", &tab[i].preid);
                                    break;
                                }
     
                                            /*if (strcmp(ligne_lue,tableau)==0)
                                                {
                                                    do
                                                    {
                                                        fscanf(batch,"%*[^(](%99[^)])", &tab[i].preid);
                                                        break;
                                                    }while (strcmp(ligne_lue,tableau1)==0);*/
                        }
    printf("%s\n", tab[i].id);
    printf("%s\n", tab[i].descr);
    printf("%s\n", tab[i].owner);
    printf("%s\n", tab[i].preid);
     
    fclose(batch),batch=NULL;
    return 0;
     
    }
    Pour la détermination d'un bloc, cela fonctionne très bien.Je vois en mode debogage que la lecture s'éxécute, j'arrive avec la condition a remplir une structure (break sur la ligne) (pas encore de manière optimale a cause du placement des informations dans le fichier mais j'y travaille).

    Mes interrogations sont les suivantes :

    1)Quand je ne met pas de break, cela fait fermé codeblock, le doublon fscan est-il une erreur pour reprendre la lecture ou je l'ai laissé après l'attribution dans la structure?
    2)Je souhaite par la suite prendre id de la structure, le transformé en key puis stocké dans une table de hashage pour créé une sort de key plus data qui me permettra de lier les structures ensembles mais je ne vois pas comment m'y prendre

    Merci

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Beaucoup de problèmes dans ton code
    • ta fonction "cptLignes" lit tout le fichier. Normal. Mais une fois le fichier lu, il ne peut plus être "relu". Il te faut te repositionner au début (d'ailleurs tu as mis un rewind() sauf que ce n'est pas le bon paramètre). Si vraiment tu veux faire ça propre, il faudrait alors qu'elle mémorise la position du fichier (ftell), se positionne au début (rewind), lise tout (fgets) puis se repositionne à la position initiale (fseek) avant de renvoyer le nb de lignes. Et surtout ne pas fermer le fichier.
    • en cas d'erreur d'ouverture du fichier "batch" tu sors de la fonction. Qu'en est-il alors du fichier "extract" ouvert lui-aussi ?
    • on ne met pas de "&" devant un nom de tableau, c'est déjà une adresse
    • tu as créé un type "application" (tu aurais pu l'appeler "t_application" pour être plus standard) mais tu ne l'utilises même pas


    Sinon pour tes interrogations je n'y pige rien. Une fois que tu as trouvé l'info tu sors de la boucle (normal). Si tu n'en sors pas, alors ta boucle continue sauf que tu ne dois plus lire autant de lignes que ce qu'il y en a dans le fichier puisque tu en as lu 4 de plus !!! D'où crash !!!
    Et pour ta table de hashage ben désolé, comme ça n'existe pas en C faut que tu te la crées "à la main". Il y a des conseils à ce propos sur le net. Le cas le plus délicat étant de gérer un même hash pour plusieurs clefs différentes. Mais si c'est juste une question de tri, t'as alors qsort() qui peut t'aider...
    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]

  3. #3
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2015
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2015
    Messages : 105
    Par défaut
    Merci Sve@r de ta réponse,

    je vais t'éclairer sur les points que tu énumère en sachant très très surement que tu en connait beaucoup plus que moi.

    1) j''ai compris que je faisais cela comme un cochon.En fait, oui je lis tout le fichier et je veux que le nombre de ligne soit pour moi connues=>je peux par la suite connaitre le nombre de ligne pour le fscan et m'assurer que tout le txt est lu (je voyais cela comme ca mais c'est peut etre erroné).

    2)J'ai laissé le fichier extract parce que il "m'aurait" servi a noté mes structures pour vérification des données récupérées

    3)j'ai crée un tableau mais mon souhait et ce sur quoi je suis maintenant c'est, comme je l'ai explicité:

    Mon paragraphes commence avec le mot adstart et j'ai une fonction qui me dit combien j'ai de fois cet ADSTART dans mon txt => malloc pour allouer mes structures dynamiquement.

    Aurais-tu,avec ces informations, le moyen de me répondre a ces problématiques?

    1) Le renvoie des lignes cause la perte des fscan de la fonction "main"? ou une manipulation connue qui permet de lire PUIS écrire a chaque détection de ADSTART et à la fin de cette écriture reprendre l'écriture à la position de fin de paragraphe.

    Pour la fonction Hash, je ferais cela quand les structure seront déja bien utilisée.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par nysay27 Voir le message
    1) j''ai compris que je faisais cela comme un cochon.En fait, oui je lis tout le fichier et je veux que le nombre de ligne soit pour moi connues=>je peux par la suite connaitre le nombre de ligne pour le fscan et m'assurer que tout le txt est lu (je voyais cela comme ca mais c'est peut etre erroné).
    Oui mais ce que tu ne comprends pas, c'est que si tu lis comme tu le fais 4 lignes de plus (tes 4 fscanf), tu dois alors les comptabiliser. Parce que sinon tu es décalé entre le nombre de lignes lues et le nombre de lignes restant à lire dans ta boucle.
    Ceci dit, tu veux t'assurer que "tout est bien lu". Ca signifie que tu ne fais pas confiance à la fonction de lecture ? Mais comme tu as utilisé une fonction de lecture pour compter le nb de lignes, ça devient incohérent non ? Pourquoi en effet faire confiance dans un cas et pas dans l'autre ? Comment alors admettre que le nb de lignes est correct ???

    Personne ne fait comme ça. A la base tout le monde fait confiance à la lecture pour tout lire. De plus tu as une variable globale "errno" qui prend systématiquement une valeur non nulle chaque fois qu'il y a un pb système (et le message correspondant au soucis est disponible dans strerror(errno)). Et enfin il existe deux fonctions feof() et ferror() qui renvoient vrai/faux si la fin de lecture a été causée par une fin normale de fichier ou par une erreur de lecture (fonctions opposées l'une l'autre). Donc si vraiment tu n'as pas confiance, tu peux après ta boucle utiliser un de ces outils pour vérifier la cause de l'arrêt de lecture...

    Citation Envoyé par nysay27 Voir le message
    2)J'ai laissé le fichier extract parce que il "m'aurait" servi a noté mes structures pour vérification des données récupérées
    Ce que je voulais dire, c'est que quand tu fais une gestion d'erreurs tu dois la faire en entier. Tu ouvres un fichier. Il ne s'ouvre pas alors tu sors, ok. Ensuite tu fais un malloc. L'allocation ne se fait pas, alors tu dois fermer le fichier ouvert avant de sortir. Puis tu ouvres un second fichier. Il ne s'ouvre pas alors tu dois libérer le malloc et fermer le premier fichier avant de sortir. Et etc.
    Ca peut vite devenir lourd et répétitif. Une bon façon de réduire ça au minimum est d'utiliser le goto...
    Code c : 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
    int fct()
    {
        FILE *f1=NULL;
        FILE *f2=NULL;
        char *pt=NULL;
        errno=0;
     
        if ((f1=fopen(...)) == NULL)
        {
            fprintf(stderr, "Erreur fopen(f1) - %s\n", strerror(errno));
            goto sortie;
        }
     
        if ((f2=fopen(...)) == NULL)
        {
            fprintf(stderr, "Erreur fopen(f2) - %s\n", strerror(errno));
            goto sortie;
        }
     
        if ((pt=malloc(...)) == NULL)
        {
            fprintf(stderr, "Erreur malloc() - %s\n", strerror(errno));
            goto sortie;
        }
     
        ... (suite du code)...
     
        sortie:
        if (f1) fclose(f1);
        if (f2) fclose(f2);
        if (pt) free(pt);
        return -errno;  // Perso j'aime bien renvoyer un nb négatif quand il y a un soucis...
    }

    Hé oui, le goto a beau être abhorré, il rend parfois des services quand il est utilisé finement...

    Citation Envoyé par nysay27 Voir le message
    3)j'ai crée un tableau mais mon souhait et ce sur quoi je suis maintenant c'est, comme je l'ai explicité:
    Je parlais du type. Tu crées un type mais tu utilises la notation "struct" pour déclarer une variable...

    Citation Envoyé par nysay27 Voir le message
    Mon paragraphes commence avec le mot adstart et j'ai une fonction qui me dit combien j'ai de fois cet ADSTART dans mon txt => malloc pour allouer mes structures dynamiquement.
    Pourquoi ne pas créer une fonction qui compte les mots spécifiés ? C'est bien les petites fonctions dédiées à un travail bien précis...
    Code c : 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
    int cptMot(FILE *fp, char *mot)
    {
        long pos;
        char buf[100];
        char *pt;
        pos=ftell(fp);
        rewind(fp);
     
        cpt=0;
        while (fgets(buf, 100, fp))
        {
            if ((pt=strchr(buf, '\n')) != NULL) *pt='\0'   // Suppression '\n'
            if (strcmp(buf, mot) == 0) cpt++;
        }
        fseek(fp, pos, SEEK_SET);
        return cpt;
    }
    En considérant bien entendu que le mot se trouve seul sur sa ligne...

    Citation Envoyé par nysay27 Voir le message
    1) Le renvoie des lignes cause la perte des fscan de la fonction "main"? ou une manipulation connue qui permet de lire PUIS écrire a chaque détection de ADSTART et à la fin de cette écriture reprendre l'écriture à la position de fin de paragraphe.
    Tu dois gérer en permanence ta position pour pouvoir revenir écrire puis repartir lire. En sachant qu'un fichier n'étant qu'une suite d'octets, tu ne feras que repasser sur des octets déjà existants donc si tu n'écris pas exactement autant que ce qu'il y a ça devient incohérent. Si par exemple ton fichier contient "barbapapa" et que tu reviens sur le "papa" parce que tu veux le remplacer par un "x" çà donnera alors "barbaxapa" au lieu de "barbax"...
    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. [XL-2007] Lecture et écriture dans un fichier .txt en VBA
    Par zanys dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 25/05/2011, 09h45
  2. [PERL]Prob lecture/écriture dans un fichier ".TXT"
    Par Magcom dans le forum Langage
    Réponses: 8
    Dernier message: 29/07/2010, 10h36
  3. Lecture de données dans un fichier txt
    Par Marcusss dans le forum MATLAB
    Réponses: 6
    Dernier message: 03/04/2007, 14h40
  4. Lecture de valeurs dans un fichier texte (txt)
    Par zerbault dans le forum Fortran
    Réponses: 2
    Dernier message: 22/01/2007, 10h29
  5. Lecture répétitive dans un fichier txt
    Par Didine95 dans le forum Langage
    Réponses: 9
    Dernier message: 20/07/2006, 14h30

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