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

Fortran Discussion :

[Fortran 90] Choix de séparateur pour lecture dans un fichier


Sujet :

Fortran

  1. #1
    Candidat au Club
    Inscrit en
    Septembre 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut [Fortran 90] Choix de séparateur pour lecture dans un fichier
    Bonjour

    J'espère que ma question ne se trouve pas déja dans les archives, j'ai recherché à la main puis avec le moteur sans trouver. Désolé si c'est le cas.

    En gros j'ai un fichier de donnée que j'ai enregistré au format csv, les différentes valeurs sont donc séparées par des virgules. Je voudrai savoir si vous connaissez un moyen pour que le caractère virgule soit reconnu comme un séparateur lors de la lecture dans fortran90?

    Je vais vous donner un exemple de ce que je fais pour montrer pourquoi je demande ca.

    J'ai dans mon fichier de données des lignes de type:
    "toto,374.2,1438.558413,24.87403093,142.4000" *ligne de type 1
    "t,380.6,1438.079111,24.87407659" *ligne de type 2

    Pour l'instant ma lecture se fait en utilisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    wfile=10
    OPEN(UNIT=wfile,FILE=namefile1,FORM="FORMATTED",STATUS="OLD",ACCESS="sequential",ACTION="read")
    READ(wfile,FMT='(A,F7.2,F12.8,F12.8)') dummy,tread, xread, pread
    READ(wfile,FMT='(A,F7.2,F12.8,F12.8)') dummy,tread, xread, pread
    close(wfile)
    Avec dummy de type CHAR(1) un string de dimension 1 parce que la plupart des lignes ne contiennent pas de string au debut (type 2) et pour l'instant j'ai une subroutine qui va d'abord chercher la ligne de type 1 et commence a lire les donnees en utilisant la lecture ci-dessus a ligne suivante, de type 2 (donc sans probleme).

    Maintenant je voudrais lire les donnees en position 2 et 3 sur toutes les lignes (meme celles de type 1) . Avec la ligne de commande precedente, ca ne marche pas avec les lignes de type 1 puisque apres avoir lu 1 caractere, il commence a lire le reste du texte pour l' affecter dans un reel, donc plantage. Si je change le type de dummy pour char(50) en supposant que 50 soit la longueur de la chaine de caractere dans le type 1, c' est pour le type 2 que la partie numerique va etre lue dans dummy.

    Du coup il serait tres pratique que la virgule soit reconnue comme un separateur : la lecture prendrait un string de longueur 1, puis sauterait apres le separateur pour lire la deuxieme valeur.

    Est ce que vous auriez une piste sur comment faire ca ? Ca doit etre simple mais j'ai pas trouve de reponse dans les cours de fortran que j'ai pu trouver en ligne.

    En regle generale, existe-t-il un separateur naturel dahs fortran90 lors de lecture ou est-on toujours oblige de connaitre la longueur de ce qu' on veut lire ?

    Merci d' avance pour votre aide !

  2. #2
    Candidat au Club
    Inscrit en
    Septembre 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut une solution mais pas au probleme general
    Bon j'ai trouvé une ruse pour mon cas particulier, j'utilise un read avec advance=no sur un caractere et je continue tant que le caractère lu n'est pas une virgule. Après, je n'ai plus qu'a lancer la lecture des trois variables réelles, sans paramètre advance et rebelote sur la ligne suivante.

    En langage fortran90 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    i=0
    OPEN(UNIT=wfile,FILE=namefile1,FORM="FORMATTED",STATUS="OLD",ACCESS="sequential",ACTION="read")
    do WHILE (i.LT.6)
       i=i+1
       lengthnotcoma=0
       testcoma='B'
       DO WHILE (testcoma.NE.',')
          READ(wfile,FMT='(A)',ADVANCE='NO') testcoma
       END DO
       READ(wfile,FMT='(F7.2,F12.8,F12.8)') a(i),b(i),c(i)
    END DO
    CLOSE(wfile)
    Voilà, c'est bon mais je serais toujours intéressé si quelqu'un connaissait la réponse sur d'éventuels séparateurs possible lors de la lecture de données. Ca serait super pratique je trouve.

  3. #3
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut
    Tout d'abord en ce qui concerne le séparateur "naturel" en F90, c'est tout simplement un (ou plusieurs) espaces.

    Donc si tu as sur une ligne du fichier 18
    tu peux la lire simplement sans préciser de format avec

    ou i1 i2 et i3 sont de type integer !

    Ensuite pour ton cas particulier si tu as des virgules. Tu peux commencer par lire toute la ligne dans une variable caratère que j'appelle ligne

    tu déclare

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    character(len=100)::ligne
    ensuite tu lis ta ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read(10,"(a)")ligne ! ici le format a est important pour ne pas lire que le premier mot
    ensuite tu cherche les virgules avec la commande index

    tu écrit dans k la position de la première virgule. Si ensuite tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    k2 = index(ligne(k+1:),",")
    tu mets dans k2 la postition de la première virgule à partir de k2 +1 soit la deuxième de ta ligne.

    Ensuite

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read(ligne(k+1:k2-1),*)variable
    tu récupère comme ça ce qu'il y a entre k et k2 !

    Ceci dis c'est un peu lourd .... mieux vaut avoir des fichiers avec des espaces comme séparateur !

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    cuicuimusic :

    Tu n'indique nulle part pourquoi tu ne peux pas utiliser une lecture list-directed (format * dans le read). À moins qu'il y ait une contrainte à ton problème que tu n'indique pas dans ta description, la lecture list-directed fait exactement ce que tu veux.

    La lecture devient alors simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    wfile=10
    OPEN(UNIT=wfile,FILE=namefile1,FORM="FORMATTED",STATUS="OLD",ACCESS="sequential",ACTION="read")
    READ(wfile,FMT=*) dummy,tread, xread, pread
    READ(wfile,FMT=*) dummy,tread, xread, pread
    close(wfile)
    La longueur de dummy n'a pas beaucoup d'importance : c'est la position du séparateur (virgule) qui a préséance.

    Ladgalen :

    Je crois que le séparateur privilégié pour la lecture list-directed est plutôt la virgule (et non l'espace). La virgule permet de gérer les données manquantes, ce que les espaces ne peuvent pas faire.

  5. #5
    Candidat au Club
    Inscrit en
    Septembre 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Je me disais bien qu'il devait y avoir plus simple

    Mais en utilisant ce type de lecture, va-t-il reconnaitre mes réels tels qu'ils sont ? Bon je vais essayer, je vous dirai ! Merci pour votre aide (et désolé pour ma réponse tardive je pensais que je recevrais un email quand quelqu'un aurait répondu).

  6. #6
    Candidat au Club
    Inscrit en
    Septembre 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci beaucoup, J'ai essayé et ça marche.

    Par contre il est a noter que dans le cas où toto est une chaine de caracteres contenant des espaces, la methode de sylvain ne marche pas, car fortran90 (en tous cas l'interpretation qu'en fait le compilateur que j'utilisse, f90) considere les espaces aussi comme des separateurs.

    Du coup en m'inspirant de vos deux conseils, j'ai fait (où ligne est une chaine de caractere de longueur suffisante pour contenir les variables que je veux lire):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
          READ(wfile,FMT='(A)'),ligne
          k=index(ligne,',')
          IF ((k.NE.0).AND.(ligne(1:3).NE.'END')) THEN
             READ(ligne(k+1:),FMT=*) timeread,deltaread,loadread
          END IF
    Et ca marche très bien. Encore merci pour votre aide !!

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

Discussions similaires

  1. [Débutant] Afficher un pdf pour lecture dans windows form
    Par Youpsy dans le forum VB.NET
    Réponses: 1
    Dernier message: 27/12/2012, 13h21
  2. aide pour lecture dans un fichier
    Par hichamo dans le forum C
    Réponses: 9
    Dernier message: 01/05/2007, 10h46
  3. Chemin pour lecture dans un répertoire
    Par vva dans le forum ASP
    Réponses: 2
    Dernier message: 09/03/2007, 10h16
  4. Réponses: 12
    Dernier message: 14/06/2004, 13h06
  5. [VB6] Api pour supprimer dans un fichier INI
    Par Argonz dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 20/02/2003, 08h16

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