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 :

Paramétriser la lecture d'un fichier texte


Sujet :

Fortran

  1. #1
    Vol
    Vol est déconnecté
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 42
    Points : 38
    Points
    38
    Par défaut Paramétriser la lecture d'un fichier texte
    Bonjour,
    J'ai un fichier texte qui ressemble à quelque chose comme ceci. Le nombre de colonnes est fixe mais le nombre de lignes (1000+) varie d'un fichier à un autre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    1    80,9015579200    58,7787246700    100,0000000000
    2    30,9003887200    95,1060791000    100,0000000000
    3    -30,9015693700    95,1056900000    100,0000000000
    4    -80,9029464700    58,7768058800    100,0000000000
    5    -100,0000000000    -0,0000180993    100,0000000000
    6    -80,9003143300    -58,7804298400    100,0000000000
    7    -30,9010887100    -95,1058502200    100,0000000000
    8    30,9034862500    -95,1050720200    100,0000000000
    9    80,9029388400    -58,7768211400    100,0000000000
    10    100,0000000000    0,0000000000    66,6666641200
    11    80,9015579200    58,7787246700    66,6666641200
    12    30,9003887200    95,1060791000    66,6666641200
    13    -30,9015693700    95,1056900000    66,6666641200
    J'aimerais lire ce fichier et le stocker dans un tableau. J'utilise Compaq Visual Fortran et j'ai essayé de comprendre le help pour faire une lecture mais sans succès. J'ai chercher pour trouver des exemples sur le net mais en vain. Si quelqu'un pouvait me diriger vers un exemple concret et complet ou bien me donner la syntaxe pour effetuer la lecture, j'apprécierais beaucoup.
    Merci!

    p.s. J'utilise Fotran90. Je dois traduire un programme Matlab en Fortran, je viens tout juste de commencer à travailler avec Fortran.

    edit: Après plusieurs heures de tentatives, j'ai trouvé comment lire mon fichier. Par contre, je n'ai pas réussi à paramétriser l'algorithme aussi bien que je l'aurais voulu.

    Tout d'abord, je veux stocker le nom du fichier dans une variable (filename). Pour que la commande OPEN puisse fonctionner, je dois indiquer le nombre de caractère lors de l'instanciation de la variable de type CHARACTER. Est-ce qu'il y aurait moyen d'utiliser l'instanciation CHARACTER(LEN=*) (ou autre chose permettant quelque chose de similaire) et ensuite de redimensionner la variable. Ainsi, il serait possible de changer facilement le nom du fichier.

    Ensuite, pour le tableau contenant les données, je veux le dimensionner selon le nombre de lignes contenus dans le fichier. Je n'ai pas trouvé de commande pour obtenir directement le nombre de lignes contenues dans le fichier. Donc, j'ouvre une première fois le fichier et je compte le nombre de lignes. Ensuite, je dimensionne mon tableau et par la suite, je réouvre le fichier et je le relis une deuxième fois, mais cette fois, j'enregistre les données dans mon tableau. Est-ce qu'il y aurait moyen d'effectuer cela sans avoir à ouvrir le fichier deux fois? Ou tout autre méthode qui serait plus optimale? (J'ai l'impression que ma méthode utilisée n'est pas très bonne côté temps d'exécution...)

    Voici ce que j'ai fait jusqu'à maintenant:
    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
    program Test1
     
        implicit none
     
        character(len=15) :: filename
        integer :: i,j,nbNode,nbCol
        integer :: unitFile, iError,line
        double precision, allocatable :: fileContent(:,:)
        double precision, allocatable :: temp(:)
     
        nbNode = 0
        nbCol = 4
     
        allocate (temp(nbCol))
     
        unitFile = 1
        filename = "nodeMeshBig.txt"
     
        ! Ouvrir le fichier
        open(UNIT=unitFile, FILE=filename, FORM="FORMATTED", STATUS="OLD", ACTION="READ")
     
        ! Déterminer le nombre de lignes dans le fichier
        countLines: do
     
            read(UNIT=unitFile, FMT=*, IOSTAT=iError) temp
     
            if (iError == -1 .OR. iError > 0) then 
                exit
            else
                nbNode = nbNode + 1
            end if
     
        end do countLines
     
        close(UNIT=unitFile)
     
        ! Définir la dimension du tableau selon le nombre de lignes dans le fichier
        allocate (fileContent(nbNode,nbCol))
     
        ! Réouvrir le fichier
        open(UNIT=unitFile, FILE=filename, FORM="FORMATTED", STATUS="OLD", ACTION="READ")
     
        ! Stocker les données du fichier dans un tableau
        saveNodes: do line = 1,nbNode
     
            read(UNIT=unitFile, FMT=*) fileContent(line,1:nbCol)
     
        end do saveNodes
     
        close(UNIT=unitFile)
     
        ! Vérification
        write(*,*) size(fileContent(:,1))
     
        do i = 1,nbNode
            do j = 1,nbCol
     
                write(*,*) fileContent(i,j)
     
            end do
        end do
     
    end program Test1

  2. #2
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 79
    Points : 89
    Points
    89
    Par défaut
    Bonjour,
    je n'ai pas réellement de solutions à tes problèmes...tout au plus des "bidouilles" que j'ai moi même utilisé face à ce genre de question .
    Pour la longeur de ta variable fichier....euh, est-ce vraiment limitant à ce point de déclarer une longeur "large" leng=100 qui permettrait de stocker la plupart des noms de fichiers ?
    Pour la double lecture du fichier...c'est vrai que ça peut faire pas propre comme code...moi, je m'en contente à l'exception près que j'utilise la commande rewind en fin de première lecture, comme celà tu n'as pas à faire un close(unit) puis open(unit)
    Mais là, je ne sais même pas si on a un gain de temps et si il n'y a pas de risques
    Autrement, sous unix pour éviter une lecture ne servant qu'au compte des lignes, j'utilise assez souvent un WC -l sur mon fichier que je redirige vers le programme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    wc -l fichier > programme_fortran
    et je met comme première instruction dans mon programme un
    Personnellement je travaille sur des gros fichiers (plusieurs centaines de milliers de lignes) avec une grosse machine, donc....tant que le calcul se fait dans un temps raisonnable, je ne perds pas trop de temps à optimiser...mais si quelqu'un à une astuce pour faire le travail plus proprement, je suis preneur.

  3. #3
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par yogitetradim
    Personnellement je travaille sur des gros fichiers (plusieurs centaines de milliers de lignes) avec une grosse machine, donc....tant que le calcul se fait dans un temps raisonnable, je ne perds pas trop de temps à optimiser...mais si quelqu'un à une astuce pour faire le travail plus proprement, je suis preneur.
    Il faut utiliser la valeur de iostat retournee par read(), comme presente dans ce post.

    Pour le reste, c'est de la gestion de memoire dynamique, a coup de allocate() et en utilisant une fonction reallocate() telle que celle presentee ici, par exemple. Il est souvent utile de faire le module d'I/O en C (qui se prete mieux a ce genre de choses) et le coeur du programme en Fortran.

    EDIT: iostat est retourne par read(), non par open() comme indique par erreur dans la premiere version du post. Merci a yogitetradim.

  4. #4
    Vol
    Vol est déconnecté
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 42
    Points : 38
    Points
    38
    Par défaut
    Merci beacoup pour les réponses, je peux maintenant faire exactement ce que je voulais
    Citation Envoyé par yogitetradim
    Pour la longeur de ta variable fichier....euh, est-ce vraiment limitant à ce point de déclarer une longeur "large" leng=100 qui permettrait de stocker la plupart des noms de fichiers ?
    Puisque la déclaration character(len=*) ne fonctionnait pas j'ai cru qu'il fallait indiquer le nombre exacte de caractères pour que la commande READ fonctionne. Je n'avais donc même pas essayé de mettre une valeur supérieure... Grosse erreur de ma part. Merci!

    Citation Envoyé par DaZumba
    Il faut utiliser la valeur de iostat retournee par read(), comme presente dans ce post.

    Pour le reste, c'est de la gestion de memoire dynamique, a coup de allocate() et en utilisant une fonction reallocate() telle que celle presentee ici, par exemple. Il est souvent utile de faire le module d'I/O en C (qui se prete mieux a ce genre de choses) et le coeur du programme en Fortran.
    Super la fonction pour redimensionner les tableaux. Ce sera très pratique. Je ne connaissais pas la commande du pointeur ( => ), ce sera aussi très utile. Je vais donc redimensionner mon tableau au fur et à mesure que je lis le fichier. Ce sera beacoup plus propre selon moi. Merci!

    Une dernière question. Pour un fichier contenant entre 1k et 10k lignes. Par combien de lignes à la fois serait-il préférable de redimensionner le tableau? Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Je crée un tableau de 1000 lignes
    Je lis les 1000 premières lignes du fichier
     
    S'il y a une 1001e ligne, j'augmente la taille du tableau de nbLigne=100
    Je lis les 100 autres lignes du fichier
        (ou arrêt avant et redimension du tableau selon le nombre exact de lignes lues)
     
    S'il y a une 1101e ligne, j'augmente la taille du tableau de nbLigne=100
    Je lis les 100 autres lignes du fichier
        (ou arrêt avant et redimension du tableau selon le nombre exact de lignes lues)
     
    Continuer jusqu'à la fin du fichier...
    Qu'elle valeur de nbLigne serait suggérée? Sans être la valeur optimale, qu'elle serait une valeur qui aurait du bon sens?
    Après réflexion, serait-il préférable de définir un tableau plus grand (> 10k) et ensuite de le redimensionner selon le nombre exact de lignes?

    Concernant ma dernière question, je me casse probablement la tête sur des détails qui sont totalement négligeable par rapport à l'ensemble de mon application. J'indique donc résolu et tant mieux si quelqu'un répond toutefois à ma question non triviale

    Merci!

  5. #5
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    C'est une question plutôt algorithmique que tu poses en fait à la fin de ton post.
    Généralement la solution adoptée est de doubler à chaque fois qu'on atteint la limite, on aboutit ainsi à une complexité amortie d'ajout d'un élément en O(1) (temps constant).
    D'un autre côté dans ton cas, une heuristique bien fondée sur la longueur attendue de tes fichiers peut-être plus efficace (par ailleurs peut-être (sans doute) serait-il plus efficace de lire ton fichier une première fois par gros blocs et de compter les caractères de fin de ligne pour en déduire la longueur nécessaire).

    --
    Jedaï

  6. #6
    Vol
    Vol est déconnecté
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 42
    Points : 38
    Points
    38
    Par défaut
    Ouin, c'est vrai, c'est de l'algo... je ne voulais pas créer un nouveau post seulement pour cette question. Merci d'avoir quand même répondu
    Je vais utiliser ta suggestion de doubler à chaque fois que la limite est atteinte. Ça semble bien.

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

Discussions similaires

  1. Lecture d'un fichier texte dans un projet TOMCAT
    Par brice_nice dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 03/07/2005, 15h04
  2. lecture d'un fichier texte
    Par benahpets dans le forum MFC
    Réponses: 5
    Dernier message: 22/06/2005, 11h50
  3. [C#] Lecture d'un fichier texte (farfelu)
    Par choas dans le forum Windows Forms
    Réponses: 3
    Dernier message: 11/04/2005, 14h33
  4. Lecture d'un fichier Texte
    Par jcharles dans le forum Bases de données
    Réponses: 8
    Dernier message: 27/10/2004, 14h58
  5. Stockage de données & lecture d'un fichier texte
    Par petitours dans le forum C++Builder
    Réponses: 6
    Dernier message: 13/03/2004, 14h05

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