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 de fichier : fin de ligne


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut lecture de fichier : fin de ligne
    Tout d'abord bonsoir à tous et merci de l'attention que vous porterez à ce message. Je suis entrain de réaliser un projet en c qui traite diverses informations. Je récupère ces informations dans des fichiers texte, ligne par ligne avec un fgets. Elles sont ensuite distribuées entre plusieurs variables de la manière qui suit :

    - j et k prenne la valeur 0 (début du tableau copie qui contient une ligne du fichier)
    - j va ensuite se placer a la fin du premier élément avecun while(!isspace(copie[j])) pour l'encadrer
    - avec un for(l=k,l<j,l++) le programme recopie dans la variable correspondante
    - j avance au début de l'élément suivant, k prend sa valeur, j avance jusqu'à l'espace suivant et ainsi de suite

    le premier élément de la ligne est souvent un nombre récupéré par i, qui sert d'indice dans un tableau, n,m et o sont utilisés pour parcourirs d'autres tableaux.

    Le problème que je rencontre est localisé en rouge dans le code qui suit :

    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
    FILE *fic1;
    /*FILE *fic2;
    FILE *fic3;
    FILE *fic4;*/
    char copie[N];
    char temp[N];
    nt i,j,k,l,m,n/*,o*/;
    
    fic1 = fopen("pays.txt","r");  //ouverture fichier en ecriture
    if ( fic1 == NULL ) {          //vérif erreur
    
    printf("erreur d'ouverture\n");
    } else {
    while(!feof(fic1)){ //jusqu'à fin fichier
    fgets(copie,N,fic1); //copie de la ligne
    printf("%s",copie);
    j=0; //initialisation début
    k=0;
    while (!isspace(copie[j])){ //recherche fin
    j++;
    }
    m=0; //compteur
    for(l=k;l<j;l++){ //parcours numéro
    temp[m]=copie[l]; //copie numéro m++;
    } temp[m]='\0'; i=atoi(temp); //printf("%d",i); j++; k=j; while (!isspace(copie[j])){ //recherche fin nom
    j++;
    } m=0; //compteur for(l=k;l<j;l++){ //parcours nom
    listepays[i].nom[m]=copie[l]; //copie nom m++;
    } //printf("%s",listepays[i].nom); j++; k=j; //récupération début mot while (!isspace(copie[j])){
    j++;
    } m=0; for(l=k;l<j;l++){
    listepays[i].capi[m]=copie[l]; m++;
    } //printf("%s",listepays[i].capi); j++; k=j; while (!isspace(copie[j])){
    j++;
    } m=0; for(l=k;l<j;l++){
    listepays[i].cont[m]=copie[l]; m++;
    } //printf("%s",listepays[i].cont); j++; k=j; while (!isspace(copie[j])){
    j++;
    } m=0; for(l=k;l<j;l++){
    listepays[i].gouv[m]=copie[l]; m++;
    } //printf("%s",listepays[i].gouv); j++; k=j; while (!isspace(copie[j])){
    j++;
    } m=0; for(l=k;l<j;l++){
    temp[m]=copie[l]; m++;
    } temp[m]='\0'; listepays[i].habi=atoi(temp); //printf("%d",listepays[i].habi); n=0; //initialisation compteur while(copie[j] != '\0'){ //jusqu'à fin ligne copiée
    j++; k=j; while (!isspace(copie[j])){
    //printf("%c",copie[j]); j++;
    } m=0; for(l=k;l<j;l++){
    listepays[i].rich[n][m]=copie[l]; m++;
    } //printf("%s",listepays[i].rich[n]); n++;
    }
    }
    } fclose(fic1);
    Il y a différent printf en commentaires dans le programme, ils servent a tester si les différentes variables sont bien remplies. En arrivant a listepays.rich on est en bout de ligne dans le fichier, les différents éléments, en nombre indéterminé, sont bien tous copiés mais ensuite des tas de caractères bizars s'affichent a la suite. Avec le printf sur j dans la boucle while(!isspace(copie[j])) on obtient la même chose sans les espaces, suite a quoi, mélé aux caractères bizars, apparait un baratin sur windows, le processeur, ...

    Je ne sais plus quoi faire. Le while(!isspace(copie[j])) avait été précédemment corrigé. Avant correction la boucle while(!feof(fic1)) se réalisait mais maintenant plus. Cela ajouté au problème précédent me met en déroute, on est trois a tester et rien y fait on arrive pas à résoudre le problème. Si quelqu'un identifie l'erreur, je lui en serait très reconnaissant.

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Nariom Voir le message
    Tout d'abord bonsoir à tous et merci de l'attention que vous porterez à ce message. Je suis entrain de réaliser un projet en c qui traite diverses informations. Je récupère ces informations dans des fichiers texte, ligne par ligne avec un fgets. Elles sont ensuite distribuées entre plusieurs variables de la manière qui suit :
    <...>

    Je ne sais plus quoi faire. Le while(!isspace(copie[j])) avait été précédemment corrigé. Avant correction la boucle while(!feof(fic1)) se réalisait mais maintenant plus. Cela ajouté au problème précédent me met en déroute, on est trois a tester et rien y fait on arrive pas à résoudre le problème. Si quelqu'un identifie l'erreur, je lui en serait très reconnaissant.
    Il y a 2 aspects à considérer

    1 - ton codage est-il correct ? Peut être, pour le moment, je ne sais pas... (ne compile pas... N non défini etc.)
    2 - ta conception est-elle correcte ? Et là, j'ai un doute quand je te vois faire des petites boucles caractères par caractères...

    C'est pourtant le plus important. Pour faire la conception correctement, on a besoin d'une défintion sérieuse :

    Montre un exemple de fichier à analyser et explique quels sont les champs à extraire.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    La il manque un bout du code, je voulais pas surcharger le message (ça c'est le main, et incomplet, N par exemple est définit pour tout le programme). Si je copie caractère par caractère c'est parce que j'ai une chaine qui récupère une ligne du fichier qui doit être ensuite découpée en plusieurs chaines, et parfois des entiers.

    Exemple de ce qui est traité avec cette partie du programme :

    0 france paris europe république 63 richess10 richess20 tourisme industrie impots

    Ceci est la première ligne, i récupère 0, ensuite "france paris europe république 63" sont distribuées dans plusieurs chaînes et un entier selon le processus précédemment décrit. La suite c'est les sources de richesse, et leur nombre n'est pas défini à l'avance (sinon ça pauserait pas de problème).

    On en arrive aux difficultés :

    while(copie[j] != '\0'){ devrait théoriquement arrêter le traitement à la fin de la ligne, pour ensuite recommencer avec le while(!feof(fic1)){ du début, mais ça n'est pas le cas. On partait du fait que fgets copie toute la ligne, \n compris, et ajoute le caractère de fin de chaîne \0. C'est ça qui doit être faux parce que la boucle continue sans s'arrêter (j avance ainsi petit a petit jusqu'à 1259, je sais d'ailleurs pas où il trouve des étapes intermédiaires sans espaces, ou même des espaces où s'arrêter ...).

    Ce qui sui le while(copie[j] != '\0'){ fonctionne de la même manière que le reste, avec j et k en encadrement etc.

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Nariom Voir le message
    Exemple de ce qui est traité avec cette partie du programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0 france paris europe république 63 richess10 richess20 tourisme industrie impots
    Si chaque mot est séparé par un blanc (espaces, tab, fin de ligne), c'est très simple.
    • sscanf() avec "%s" si le nombre de mots est fixe
    • strtok() ou strtok_r() (POSIX.1) si le nombre est variable.

    Ensuite, traduction des mots en valeurs numériques si nécessaire avec strtol() ou directement dans sscanf() si le format est fixe... Ca se fait en quelques lignes...

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci, j'aurais dû préciser qu'on est plus ou moins censés s'en tenir à ce qui est vu en cours. Je me doutais bien qu'il devait exister de belles fonctions toutes faites, mais manque de bol on y a pas le droit ...

    Si toi ou quelqu'un d'autre pourrait juste voir pourquoi le programme a un problème en fin de ligne svp, ce serait sympa.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Nariom Voir le message
    Merci, j'aurais dû préciser qu'on est plus ou moins censés s'en tenir à ce qui est vu en cours. Je me doutais bien qu'il devait exister de belles fonctions toutes faites, mais manque de bol on y a pas le droit ...

    Si toi ou quelqu'un d'autre pourrait juste voir pourquoi le programme a un problème en fin de ligne svp, ce serait sympa.
    J'ai un peu passé l'age de réinventer la roue...

    Une chose quand même. feof() ne fait pas ce que tu crois. Pour détecter la fin de lecture, il faut tester la valeur retournée par la fonction de lecture. Lire la doc pour les détails.

    http://emmanuel-delahaye.developpez....s.htm#fichiers

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    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 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nariom Voir le message
    Merci, j'aurais dû préciser qu'on est plus ou moins censés s'en tenir à ce qui est vu en cours. Je me doutais bien qu'il devait exister de belles fonctions toutes faites, mais manque de bol on y a pas le droit ...

    Si toi ou quelqu'un d'autre pourrait juste voir pourquoi le programme a un problème en fin de ligne svp, ce serait sympa.
    Emmanuel t'a parlé de "feof()" que t'utilises mal (en fait faut pas l'utiliser du tout). Mais faut aussi faire gaffe car "fgets()" récupère toute la ligne. Et c'est quoi une ligne ? Ben ce sont des caractères terminés par un <return> (ou '\n'). Faut que tu le prennes en compte ce '\n'...

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Pas de problème, Emmanuel Delahaye, je comprends bien que t'aies pas que ça a faire, j'exige pas une aide, je ne fais que solliciter un éventuel coup de main. Et merci pour le feof, ta doc apporte une solution plus pratique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (fgets (ligne, sizeof ligne, fp) != NULL)
    Cela peut néanmoins poser problème dans le cas de lignes vides (on en a).

    Sve@r étant donné que le '\n' est reconnu par isspace, il nous est utile quand j dois aller à la fin du dernier mot, et il n'est pas recopié puisque de toute façon on récupère les caractères avec :

    Merci de votre aide. On trouvera bien une solution pour le problème de fin de ligne, peut être dans la doc, j'ai pas encore tout regardé.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bon, j'ai utilisé le \n pour repérer la fin de ligne en pensant que ça s'arrêterai du coup avant de copier le dernier mot (le test se fait sur copie[j] et j est bien obligé d'aller jusqu'au \n pour aller a la fin du mot) mais oh miracle ça marche quand même.

    Par contre pour le traitement suivant ça plante mystérieusement : le fgets met bien ce qu'il faut "allemagne angleterre suisse usa" dans copie (vérifié avec un printf("%s",copie) ) mais quand je fais un printf de ce qui est enregistré dans les structures de données, ça me rend ça plus "richess10 richess20 tourisme industrie impots" de la ligne précédente plus un tas de caractères bizares. Voilà le 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
     
    fgets(copie,N,fic1);
    //printf("%s",copie);
    n=0;
    j=0;
    while(copie[j] != '\n'){
     
        k=j;
        while (!isspace(copie[j])){
     
            j++;
     
        }
        m=0;
        for(l=k;l<j;l++){
     
            listepays[i].frer[n][m]=copie[l];
            m++;
     
        }
        //printf("%s",listepays[i].frer[n]);
        j++;
        n++;
     
    }

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Les caractères bizarres sont généralement un signe du manque de caractère nul à la fin d'une chaîne.

  11. #11
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Nariom Voir le message
    ta doc apporte une solution plus pratique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (fgets (ligne, sizeof ligne, fp) != NULL)
    Cela peut néanmoins poser problème dans le cas de lignes vides (on en a).
    Je ne vois pas pourquoi...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      if (ligne[0] != '\n')
      {
          ...

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    D'accord merci à tous, j'ai résolu le problème en mettant k=0; avant le while et en incrémentant j au début et non à la fin de la boucle.

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

Discussions similaires

  1. [PHP 5.0] Lecture de fichier (saut de ligne)
    Par Awery dans le forum Langage
    Réponses: 2
    Dernier message: 21/08/2012, 09h29
  2. Probleme de lecture fin de ligne/fin de fichier
    Par KiraX10A dans le forum Débuter
    Réponses: 4
    Dernier message: 15/10/2009, 13h31
  3. Lecture d'un fichier et espace de fin de ligne
    Par Toutankharton dans le forum Langage
    Réponses: 3
    Dernier message: 31/05/2009, 07h36
  4. Lecture du fichier ini 1 ligne pour chaque Textbox
    Par kazylax dans le forum VB.NET
    Réponses: 19
    Dernier message: 13/03/2008, 03h59
  5. Lecture d'un fichier par flots : fin de ligne ?
    Par Loïc B. dans le forum C++
    Réponses: 4
    Dernier message: 07/11/2007, 21h02

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