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 lignes de longueurs variables


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut lecture de lignes de longueurs variables
    Bonjour,

    Je cherche à lire un fichier composé de plusieurs lignes du type suivant:
    les textes sont séparés par des ":"
    texte:texte:entier entier entier:texte:texte:texte......
    (exemple
    T_1 : State of the Art: 12 41 35 Geriatric Medicine:Rehabilitation Medicine:Old Age Psychiatry:
    )
    Autant la lecture des deux premiers textes et des entiers se fait bien, autant la dernière série des "textes" ne se fait. En fait il ne voit pas la fin de ligne.
    (je ne suis pas le paganini du C, ecriture basic :-( )
    voici mon bout de code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    i=1;
    while(fscanf(lecture1,"%[^:]%*c %[^:]%*c",tmp1,tmp2))
    	{
    	sprintf(tasks[i],"%s",tmp2);
    	fscanf(lecture1,"%d %d %d %[^:]%*c %[^:]%*c",&start[i],&ending[i],&load[i],tmp1,tmp2);
    	while(fscanf(lecture1,"%[^:]%*s",tmp1)==1)
    		sprintf(task_comp[i],"%s",tmp1);
    	i++;
    	}
    merci par avance à toute personne qui peut me faire progresser.

    M

  2. #2
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Points : 169
    Points
    169
    Par défaut
    Pourquoi ne pas utiliser un :
    fgets()
    pour faire une lecture complete de la ligne dans le fichier et ensuite
    découper cette ligne à grand coup de strtok() ?

    Essais déjà de lire toute les ligne de ton fichier avec (par exemple) une boucle
    contenant un fgets() et affiche ligne par ligne (dans un but de debug seulement) puis découpe les en sous partie avec strtok().

    lien vers le man fgets()

    lien vers le man strtok()

    Voila

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Essais déjà de lire toute les ligne de ton fichier avec (par exemple) une boucle
    contenant un fgets()
    Je ne sais peut-être pas utilsier le fgets, mais d'après le man, il faut donner la tailel (-1) en argument. or je ne connais pas a priori le nombre de caractères que je dois lire....

  4. #4
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Points : 169
    Points
    169
    Par défaut
    Ma foi le même problème se produira pour l'utilisation du fscanf()...
    Puisque de tout façon tu doit allouer une taille de buffer qui sera au maximum la taille de la plus grande ligne.

    Je te conseillerais de voir si tu peut pas prévoir la taille de la PLUS GRANDE LIGNE et accorder ton code en conséquence...

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Points : 124
    Points
    124
    Par défaut
    Sinon tu peux utiliser la fonction gnu "getline", qui t'évite de connaître la taîlle de la ligne à lire. "man getline" pour plus d'infos

  6. #6
    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
    Personnellement, je fairais une première passe à travers le fichier afin de déterminer la taille de la ligne la plus longue, puis j'allouerais la mémoire pour un tampon de taille adéquate permettant une lecture et une analyse ligne par ligne du fichier.

    Thierry

  7. #7
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Points : 169
    Points
    169
    Par défaut
    Citation Envoyé par apesle Voir le message
    Sinon tu peux utiliser la fonction gnu "getline", qui t'évite de connaître la taîlle de la ligne à lire. "man getline" pour plus d'infos
    De toute facon, comme pour fscanf et fgets, tu doit avoir un buffer qui est alloué en conséquence pour pouvoir contenir ta ligne complete DONC peut importe la fonction que tu va utiliser tu va devoir allouer soit un buffer trop grand ou sinon, comme le dit Thierry, tu peux faire une première passe pour savoir la ligne qui a la plus grande taille.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Points : 124
    Points
    124
    Par défaut
    Citation Envoyé par rilou Voir le message
    De toute facon, comme pour fscanf et fgets, tu doit avoir un buffer qui est alloué en conséquence pour pouvoir contenir ta ligne complete DONC peut importe la fonction que tu va utiliser tu va devoir allouer soit un buffer trop grand ou sinon, comme le dit Thierry, tu peux faire une première passe pour savoir la ligne qui a la plus grande taille.
    keep cool,
    J'ai juste donné une solution, il choisit celle qui lui plaît...

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Bonsoir et merci à tous de votre aide (et en même temps désolé pour le manque de réactivité --> boulot). je m'y recolle maintenant avec beaucoup d'espoirs :-)

    Je n'ai pas eu de difficulté particulière à lire des lignes homogènes (au sens de la nature des données) du type de l'exemple que je donne ici:

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    /* data file comp.dat
    Exemple de 2 lignes (en realité des fichiers assez gros):
     
    trucmush1 : trucmush accomagne 2 : tucmush 3 non tronque du tout : et ensuite je : peux continuer comme ca : mais ne sais ou je vais arreter :   tout le probleme est la
    la deuxieme: peut etre completement :   differente
    */
     
    char tmp[1000] ;
    FILE *reading ;
     
    int main(void)
    {
    FILE *reading ;
     
    reading=fopen("datafile.dat","rt");
     
    while(fscanf(reading,"%[^:]%*c",tmp)!=EOF) printf("%s\n",tmp);
     
    fclose(reading);
     
    return 0;
    ici le caractère de séparation est le ":". tout se passe très bien.

    mais si ma ligne devient plus compliqué, au sens ou j'ai des entiers à lire et qui se trouvent toujours au 3eme, 4 et 5eme "champs", tout se complique. d'où ma question.
    pour information, j'ai essayé ce que vous avez proposé et je ne dois pas m'y prendre correctement car à part lire la ligne entière d'une façon ou d'une autre, je ne sais plus faire.

    Pour résumer, ma structure de fichier est (le "/" juste pour faciliter la lecture à l'écran, n'existe pas dans le fichier de données):

    /chaine de caractères sans blanc/blanc/entier/blanc/entier/blanc/entier/blanc/chaine de caracteres avec ou sans blancs/:/chaine de caracteres avec ou sans blancs/: /......

    ceci un nombre indéterminé de fois et on s'arrete sans les ":"

    pour l'instant je sais lire autant de chaines quelcnques séparés par un caractère dédié (ici : ) cf exemple ci dessus.
    par contre des que je me mets dans la situation réelle avec aussi des entiers à l'intérieur, je perd le contrôle et je ne sais plus rien faire!

    je ne suis même pas certain d'être clair

    et en tout cas merci encore.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Désolé.
    Je viens de me rendre compte de ma bêtise. je pensais que je lisais la ligne, mais pas du tout!
    Je lis tout le fichier. ma conclusion est donc totalement fausse!

    Je repars sur une segmentation par getline.

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Je ne suis pas fier, mais je suis passé par les fichiers (par défaut de maitrise de la lecture sur une chaine de caractères).
    Voici la solution que j'ai trouvé et qui a l'air de bien fonctionner....

    (puristes ne pas regarder)
    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
     
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
     
    /* data file comp.dat
    Exemple de 2 lignes (en realité des fichiers assez gros):
     
    T_1  qcxlodqelim  :    12  41  35 	Geriatric Medicine : Rehabilitation Medicine : Old Age Psychiatry
    T_2  jmwdkbutnsk  : 0  19  52 	 Immunology : Infectious Diseases : Trauma & Orthopaedic Surgery : Psychotherapy
    */
     
    char tmp[1000] ;
    FILE *reading, *writting, *lecture ;
    ssize_t read;
    char * line = NULL;
    size_t len = 0;
    int tempo;
     
    int main(void)
    {
    FILE *reading ;
     
    reading=fopen("comp.dat","rt");
     
    while(read=getline(&line,&len,reading)!=-1)
    	 {
    	/*printf("%zu\n",read); 
    	printf("%s",line);*/
    	writting=fopen("temporaire","wt");
    	fprintf(writting,"%s\n",line);
    	fclose(writting);
     
    	lecture=fopen("temporaire","rt");
     
    	fscanf(lecture,"%s",tmp);
    	fscanf(lecture,"%[^:]%*c",tmp);
    	printf("task title : %s ",tmp);
    	fscanf(lecture,"%d",&tempo);
    	printf("<%d>",tempo);
    	fscanf(lecture,"%d",&tempo);
    	printf("<%d>",tempo);
    	fscanf(lecture,"%d",&tempo);
    	printf("<%d>",tempo);
    	while( fscanf(lecture,"%[^:]%*c",tmp) !=EOF ) 
    		{
    		printf("|%s",tmp);
    		}
    	printf("\n");
    	fclose(lecture);
    	}
    fclose(reading);
    }

    si quelqu'un a mieux,ce serait sympa.

    merci encore à tous.

    ps: je ne suis pas certain que les règles d'usage me permettent de dire que le probème est résolu vu la qualité de ma solution. merci d'aviser.

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    rilou t'avait donné les éléments de réponse....

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    rilou t'avait donné les éléments de réponse....
    Effectivement, c'est ce que j'ai essayé de mettre en oeuvre ! (première partie du code). mais une fois la ligne lue, je n'ai pas réussi à la lire comme dans un fichier. c'est pour cette raison que je suis passé par cette demi-solution.

  14. #14
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    Avec le style de ligne comme :


    T_1 : State of the Art: 12 41 35 Geriatric Medicine:Rehabilitation Medicine:Old Age Psychiatry:


    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
     
    char *p=NULL ;
    int l = 0, j ;
     
    i=0;
     
    while(fgets(Ligne, MAX_SIZE, lecture1) != NULL )
     {
        p = strtok ( Ligne, ":\n\r"); /* Récupère T_1 */
        p = strtok ( NULL, ":\n\r"); /* Récupère State of the Art */
     
        p = strtok ( NULL, ":\n\r"); /* Récupère la chaine contenant les entiers */
     
        sscanf ( p, "%d %d %d", &start[i],&ending[i],&load[i]); /* lit les entiers */
     
        /* Trouve le début de la chaîne significative après les entiers */
        l = strlen(p);
        for ( j = 0 ; j < l ; j++ )
         if ( (isalpha(*(p+j)) != 0) && (isspace(*(p+j)) ==0) )
            {
               p = p + j ;
               break ;
            } 
     
         strcpy ( category[i], p); /* Copie la catégorie */
     
        p = strtok ( NULL, ":\n\r"); /* Récupère la chaine suivante */
        strcpy ( subcategory[i], p); /* Copie la sous-catégorie */
     
        p = strtok ( NULL, ":\n\r"); /* Récupère la chaine suivante */
        strcpy ( subsubcategory[i], p); /* Copie la sous-sous-catégorie */
     
        i++;
    }

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Avec le style de ligne comme :


    T_1 : State of the Art: 12 41 35 Geriatric Medicine:Rehabilitation Medicine:Old Age Psychiatry:


    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
     
    char *p=NULL ;
    int l = 0, j ;
     
    i=0;
     
    while(fgets(Ligne, MAX_SIZE, lecture1) != NULL )
     {
        p = strtok ( Ligne, ":\n\r"); /* Récupère T_1 */
        p = strtok ( NULL, ":\n\r"); /* Récupère State of the Art */
     
        p = strtok ( NULL, ":\n\r"); /* Récupère la chaine contenant les entiers */
     
        sscanf ( p, "%d %d %d", &start[i],&ending[i],&load[i]); /* lit les entiers */
     
        /* Trouve le début de la chaîne significative après les entiers */
        l = strlen(p);
        for ( j = 0 ; j < l ; j++ )
         if ( (isalpha(*(p+j)) != 0) && (isspace(*(p+j)) ==0) )
            {
               p = p + j ;
               break ;
            } 
     
         strcpy ( category[i], p); /* Copie la catégorie */
     
        p = strtok ( NULL, ":\n\r"); /* Récupère la chaine suivante */
        strcpy ( subcategory[i], p); /* Copie la sous-catégorie */
     
        p = strtok ( NULL, ":\n\r"); /* Récupère la chaine suivante */
        strcpy ( subsubcategory[i], p); /* Copie la sous-sous-catégorie */
     
        i++;
    }
    de retour!
    Mille fois merci pour cette aide. j'ai utilisé ta solution. et merci aussi pour toutes les contributions.

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

Discussions similaires

  1. Importer un .txt avec lignes de longueur variable
    Par polo92 dans le forum SAS Base
    Réponses: 7
    Dernier message: 06/10/2014, 11h04
  2. Lecture par bouts de chaînes de longueur variable
    Par Chavadam dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 09/08/2013, 20h29
  3. Lecture de lignes de longueur différente
    Par melreg dans le forum MATLAB
    Réponses: 4
    Dernier message: 11/08/2009, 16h43
  4. pb lecture de ligne dans un texte
    Par bidoo dans le forum C++
    Réponses: 4
    Dernier message: 22/10/2005, 13h23
  5. Pb import fichier txt avec lignes de longueurs diverses
    Par zebulon90 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 09/12/2004, 08h32

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