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 :

Gestion des sauts de ligne WIndows/Linux dans un fichier txt (valant 1 ou 2 octets)


Sujet :

Fortran

  1. #1
    Membre à l'essai
    Homme Profil pro
    Elève ingénieur ENSG
    Inscrit en
    Avril 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gers (Midi Pyrénées)

    Informations professionnelles :
    Activité : Elève ingénieur ENSG
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2013
    Messages : 16
    Points : 20
    Points
    20
    Par défaut Gestion des sauts de ligne WIndows/Linux dans un fichier txt (valant 1 ou 2 octets)
    Bonjour !

    Pour exposer rapidement la situation, je dispose d'une série de fichiers, rangés dans des dossiers par année (2011, 2012 et 2013), qui sont tous construits de la même façon :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     nomdemonfichier.txt      DUREE : 164 mn
     DUMONT D'URVILLE      Backscatter lidar LOANA
     DATE       : 14/02/2011   HEURE DEB. : 12:13:06   FIN : 14:57:47
     LATITUDE       : -66.41   LONGITUDE         :  140.01
    J'ai fait une routine qui extrait ces informations, utilisant une structure de type ENTETE adaptée, elle marche au poil :

    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
    PROGRAM Monprog
    IMPLICIT NONE
     
    ! Déclaration des types dérivés
    TYPE ENTETE
    	CHARACTER (len=20)	:: Nom_fichier
    	CHARACTER (len=14)	:: Id_Duree_Session ! Permet de récupérer "      DUREE : "
    	CHARACTER (len=3)	:: Duree_Session
    	CHARACTER (len=4)	:: Unit_Duree_Session !permet de récupérer ' mn'
    	CHARACTER (len=23)	:: Site
    	CHARACTER (len=23)	:: Instrument
    	CHARACTER (len=15)	:: Id_Date ! Permet de récupérer " DATE       : "
    	CHARACTER (len=10)	:: Date
    	CHARACTER (len=16)	:: Id_Heure_debut ! Permet de récupérer "   HEURE DEB. : "
    	CHARACTER (len=8)	:: Heure_debut
    	CHARACTER (len=9)	:: Id_Heure_fin ! Permet de récupérer "   FIN : "
    	CHARACTER (len=8)	:: Heure_fin
    	CHARACTER (len=19)	:: Id_Latitude ! Permet de récupérer " LATITUDE       : "
    	CHARACTER (len=6)	:: Latitude
    	CHARACTER (len=24)	:: Id_Longitude ! Permet de récupérer "   LONGITUDE         :  "
    	CHARACTER (len=6)	:: Longitude
    END TYPE
     
    ! Programme
     
    IMPLICIT NONE
    CHARACTER(len=255) :: Fichier !Adresse du fichier à lire
    TYPE(ENTETE) :: Header
    INTEGER (kind=4) :: ios, Size_record
     
    INQUIRE(IOLENGTH=Size_record) Header
     
    	OPEN(	UNIT=1,			&
    		FILE=Fichier,		&
    		FORM="unformatted",	&
    		ACCESS="direct",	&
    		STATUS="old",		&
    		ACTION="read",		&
    		RECL=Size_record,	&
    		IOSTAT=ios		)
     
    	IF (ios/=0) THEN
    		PRINT *,"Erreur ",ios
    	ELSE
    		READ(UNIT=1, IOSTAT=ios, REC=1) Header
    	END IF
     
    	CLOSE(UNIT=1)
     
    END PROGRAM

    .... mais seulement pour les fichiers des années 2011 et 2012 !

    En effet pour 2013, un décalage se produit à chaque saut de ligne. Par exemple, si je veux récupérer l'année dans mon fichier, en 2012 je récupère bien la chaîne de caractères "2012", alors qu'en 2013 le décalage fait que je récupère "2/20" (càd une partie du numéro du mois + le séparateur mois/année - lorsque j'ai besoin de convertir cette chaîne en entier, forcément le programme n'apprécie pas...).

    Il se trouve que les fichiers 2011 et 2012 ont leurs sauts de ligne codés sur 1 caractère (norme UTF8, sous Linux) alors que ceux de 2013 ont leurs sauts de ligne codés sur 2 caractères (codage cp1252 sous Windows).


    Quel serait le moyen le plus simple, ou le plus élégant de contourner ce problème svp ?
    • Créer une deuxième structure "ENTETE2013" qui prend en compte la taille des sauts de ligne
    • 'Recoder' tous les fichiers de 2013 en UTF-8 ? (il y en a un bon paquet, je ne sais pas comment ça se fait à la main, existe-il une solution automatisée?)
    • Une solution qui permettrait de conserver la structure telle que je l'ai créée, mais qui indiquerait à la fonction READ que les sauts de ligne ne sont pas codés de la même manière ?
    • Ou une autre solution ?



    Je vous remercie par avance pour votre aide

    Yannick.

  2. #2
    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
    Mon premier commentaire est que tes fichiers sont SEQUENTIAL FORMATTED alors que tu as décidé de les lire DIRECT UNFORMATTED ! Cela dit, je ne suis pas certain qu'une lecture séquentielle ferait la conversion automatique entre les 2 formats de fichier. Ça risque de dépendre du compilateur.

    Comme tu as déjà codé ta stratégie, je la maintiendrais.

    Piste de solution ?

    Créer une deuxième structure "ENTETE2013" qui prend en compte la taille des sauts de ligne ?

    Je testerais le champs Id_Date :
    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
    ...
    INQUIRE(IOLENGTH=Size_record) Header
     
    	OPEN(	UNIT=1,			&
    		FILE=Fichier,		&
    		FORM="unformatted",	&
    		ACCESS="direct",	&
    		STATUS="old",		&
    		ACTION="read",		&
    		RECL=Size_record,	&
    		IOSTAT=ios		)
     
    	IF (ios/=0) THEN
    		PRINT *,"Erreur ",ios
    	ELSE
    		READ(UNIT=1, IOSTAT=ios, REC=1) Header
    		if (Header%Id_Date(2:5) /= 'DATE') then
    			close(1)
    			INQUIRE(IOLENGTH=Size_record) Header2013
    			OPEN(UNIT=1, ...)
    			if (ios /= 0) then
    				...
    			else
    				read(1,...) Header2013
    ...
    'Recoder' tous les fichiers de 2013 en UTF-8 ?

    À éviter. Si tu veux vraiment le faire, je suggérerais de convertir les anciens fichiers, pas les nouveaux. Par programme (en Fortran) ? Tu devrais les traiter comme des streams, les lire caractère par caractère et interpréter les caractères de saut de ligne. Pas très compliqué.

    Une solution qui permettrait de conserver la structure telle que je l'ai créée, mais qui indiquerait à la fonction READ que les sauts de ligne ne sont pas codés de la même manière ?

    Cette piste est incompatible avec ta stratégie (unformatted sequential). Les caractères de saut de ligne ne sont traités comme des saut de lignes, mais comme des données binaires. Tu ne peux pas dire au open/read/compilateur de se décaler selon la valeur de certaines données.

    Ou une autre solution ?

    Tout recoder en sequential formatted ? C'est plus long, mais c'est l'approche la plus robuste.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Elève ingénieur ENSG
    Inscrit en
    Avril 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gers (Midi Pyrénées)

    Informations professionnelles :
    Activité : Elève ingénieur ENSG
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2013
    Messages : 16
    Points : 20
    Points
    20
    Par défaut
    Merci pour toutes ces précisions !

    Je ne sais pas si c'est la solution la plus efficace, mais mais je viens de la tester et elle fonctionne plutôt bien (évidemment le temps de traitement est sensiblement rallongé, mais ça reste vivable) : en utilisant un fichier temporaire, dans lequel je recopie mes fichiers en supprimant les '\r' (qui se trouve être le caractère supplémentaire utilisé sous Windows pour coder les retours à la ligne). Ainsi je peux utiliser la même structure directement sur mon fichier temporaire. Simplement avec ces instructions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Cmde = " cat monfichier.txt | tr -d '\r' > monfichier.temp"
    CALL SYSTEM(Cmde)
    J'ai lu sur internet que ça ne venait pas de l'encodage des caractères, mais que ce problème pouvait être causé lors du transfert des fichier par ftp d'une machine linux à une machine windows ou vice-versa... c'est à ce moment là qu'il y aurait ajout/suppression de '\r' dans les fichiers. Etrange que quelque chose se permette ou ait besoin de lire les fichiers lors du transfert ?


    En tout cas merci pour ces pistes de réflexion je les garde sous la main s'il y a besoin d'une optimisation de mon code plus tard.

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

Discussions similaires

  1. Réponses: 14
    Dernier message: 20/06/2012, 16h05
  2. [MySQL] Suppression des sauts de ligne, de • dans un texte en php
    Par missmiss89 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 20/07/2011, 14h40
  3. [XL-2007] recherche d'une ligne de texte dans un fichier txt
    Par cagelion dans le forum Excel
    Réponses: 5
    Dernier message: 25/09/2010, 19h42
  4. Gestion des sauts de ligne avec POI
    Par chrime71 dans le forum Général Java
    Réponses: 0
    Dernier message: 01/07/2010, 16h47
  5. Gestion des sauts de lignes et balises <ul>
    Par fpouget dans le forum Langage
    Réponses: 1
    Dernier message: 08/10/2009, 22h37

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