Page 1 sur 2

Conversion de fichier texte

Publié : jeu. 28/janv./2016 2:34
par ballow
Bonsoir à tous,

Avant tout, ceci est mon premier post sur ce forum :) Je suis un "pti jeune" dans le monde de PureBasic.
Avant d'exposer mon problème je tenais à dire que j'ai pas mal regardé l'aide du soft et traîné sur le forum mais je n'ai pas réussis à faire ce que je voulais...

Voici mon but :
Je voudrais récupérer un fichier texte qui contient des valeurs séparées par des tabulation et recréer un fichier en changeant l'ordre de ces valeurs. Ça, j'y arrive.
Mon problème :
Je voudrais que sur la première ligne (et uniquement la première ligne) ma variable type$ ait la valeur "hard" et sur toute les autres lignes, la valeur "auto".

Je découperais ensuite ce fichier de sortie en plusieurs fichiers texte de 200 lignes.
Je ne veux pas relire mon fichier de sortie et faire un remplacement mais plutôt lors de la création de mon fichier de sortie (ce qui, je pense, est plus "propre" non ?)

Voici la partie de mon code :

Code : Tout sélectionner

Procedure Traitement()
  
PtTableau.l
Pourcent.l

;*
;* On regarde si il y a des fichiers dans le watchfolder.
;*-------------------------------------------------------
Repeat
  FlagExamRep=1
  If WatchFolder2Tab(ReperIn$, ".plt") ; Pas de fichier dans le rep. source.
    ;*
    ;* Si oui ReperIn$ ---> ReperOut$.
    ;*--------------------------------
    For PtTableau=0 To NbFichWatch-1
      Chy$=TabRepSrc$(1, PtTableau)


            ; Chr(9) veut dire "Tabulation"
    
      If OpenFile(#Fichier, ReperIn$+Chy$) ; Ouvre le fichier plt qu'il y a dans le dossier inbox
        CreateFile(#FichierVideo, ReperOut$+Chy$+"_SGT.txt")
        Repeat
          If Eof(#Fichier)
             CloseFile(#Fichier)
             CloseFile(#FichierVideo)
             Break
          EndIf 
          Texte$ = ReadString(#Fichier )
            ID$ = StringField(Texte$, 1, Chr(9)) ; On isole l'ID
            Playtime$ = StringField(Texte$, 5, Chr(9)) ; On isole l'heure de play
            Duration$ = StringField(Texte$, 7, Chr(9)) ; On isole la durée du media
            
            
              If PtTableau=0 ;type$ = "auto"                      ; Si ligne 1 mettre "hard" et sur les autres "auto"
              Else type$ = ("hard")
              EndIf
              If PtTableau>0
              Else type$ = ("auto")
              EndIf 
              
            
            
            title$ = StringField(Texte$, 8, Chr(9)) ; On isole le titre du media
            som$ = StringField(Texte$, 6, Chr(9)) ; On isole le SOM
            ; Ci-dessous on fabrique le fichier de sortie en lui precisant ce qu'on souhaite avoir...
          WriteStringN(#FichierVideo, GetGadgetText(#String_3) + ID$ + Chr(9) + Playtime$ + Chr(9) + Playtime$ + Chr(9) + Duration$ + Chr(9) + Chr(9) + Chr(9) + type$ + Chr(9) + title$+Chr(9)+ "0" + Chr(9) + som$)
        ForEver

        
        
      EndIf




    
    Next
  EndIf
  EventID=WindowEvent()
  If EventID=#PB_Event_Gadget
    Select EventGadget()
      Case #Button_3                          ;Quitter
        Break
    EndSelect
  EndIf
  Delay(20)
ForEver
FabFichTest(ReperBIN$+#TestFile)

SetGadgetText(#Text_6, "Termine !")

ProcedureReturn #True  
  
EndProcedure
Je pense être vraiment pas loin... mais il y a un mais... :?

Merci beaucoup de vos lumières...

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 8:50
par Marc56
Bonjour,

Ton programme n'est qu'une procédure, donc difficile de tester.
Pourrais-tu donner un exemple de fichier d'entrée et de ce que tu souhaites avoir en sortie, ce serait plus simple ?
(quelques lignes suffisent, même avec des données bidon si le sujet est confidentiel)

:wink:

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 9:12
par Marc56
Exact pour OpenFile :)

On peut aussi utiliser ReadFile() qui renvoie une valeur non nulle en cas de succès, zéro sinon.
On s'évite ainsi de tester systématiquement la présence ou non du fichier
(et hop une instruction de moins (L'une des 5 qualité d'un bon programmeur est d'être fainéant à taper des trucs) :mrgreen:

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 9:31
par Mesa
Ce code me parait incorrect:

Code : Tout sélectionner

If PtTableau=0 ;type$ = "auto"                      ; Si ligne 1 mettre "hard" et sur les autres "auto"
Else type$ = ("hard")
EndIf
If PtTableau>0
Else type$ = ("auto")
EndIf
Si tu le remplaces par celui-ci, ça va mieux ?

Code : Tout sélectionner

If PtTableau=0 ; Si ligne 1 mettre "hard" et sur les autres "auto"
type$ = ("hard")
Else 
type$ = ("auto")
EndIf
M.

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 9:36
par Marc56
Exact.
Je me demande pourquoi ces deux fonctions existent, puisque ReadFile teste aussi si le fichier peut être ouvert (Renvoie une valeur non nulle en cas de succès, zéro sinon. ) ?
Je n'ai jamais testé pour savoir ce que retourne chacune deux fonctions dans le cas d'un fichier existant mais n'ayant pas de droits en lecture ? C'est peut-être là la différence ?
:?:

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 11:01
par Ar-S
Bonjour et bienvenue.

Je serai toi je créerai une liste chainée et structurée contenant les lignes de ton textes.
Il sera ainsi aisé de remplacer la ou les ligne désirée(s) et de créer tes fichiers de sorties de 200 lignes.

Concernant ton poste, pourrais tu ajouter 2 lignes de ton fichier texte qu'on puisse avoir un exemple concret ?
Merci

Voilà ce que je te propose via un fichier texte en UTF-8 contenant ces 2 lignes :
- Fichier : "fichier_texte.txt"

Code : Tout sélectionner

1	00	1h20	PB Power	SOMjeSaisPas
2	00	1h40	PB Revenge	SOMjeSaisPas

Code : Tout sélectionner

; Ar-S
Structure Ligne
   etat.s ; hard / auto
   contenu.s ; ligne entiere
             ;//// Gestion du contenu /////
   Id.s
   PlayTime.s
   Duration.s
   Title.s
   SOM.s
EndStructure

Global NewList Ligne.Ligne()



Procedure TestFile(fichier.s)
   
   If FileSize (fichier) > 0
      ProcedureReturn 1
   Else
      ProcedureReturn 0
   EndIf
   
EndProcedure



; //// Programme ////

If TestFile ( "fichier_texte.txt" ) = 1
   
   ReadFile (0,"fichier_texte.txt") 
   While Eof(0) = 0 
      AddElement (Ligne.Ligne()) 
      Ligne.Ligne()\contenu = ReadString(0)  
      Ligne.Ligne()\ID = StringField(Ligne.Ligne()\contenu, 1, Chr(9) )
      Ligne.Ligne()\Duration = StringField( Ligne.Ligne()\contenu, 3, Chr(9) ) 
      Ligne.Ligne()\Title = StringField( Ligne.Ligne()\contenu, 4, Chr(9) ) 
   Wend
   CloseFile(0) 
   
EndIf

; Affichage test

ForEach Ligne.ligne()
   Debug Ligne.Ligne()\contenu
   Debug "ID = " + Ligne.Ligne()\ID
   Debug "Titre = " + Ligne.Ligne()\Title
   Debug "Duration = " + Ligne.Ligne()\Duration
   ;etc...
   Debug "" 
Next


Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 11:08
par ballow
Waow, quelle réactivité ! :D

Pour répondre à Marc56 voici à quoi ressemble et devrait ressembler mon fichier d'entrée et de sortie :
Fichier d'entrée :

Code : Tout sélectionner

N0023313	N0132313	====NZqU	13/10/2015	07:00:00:00	00:00:00:00	00:00:05:00	TITRE DU PROGRAMME TV	TITRE DU PROGRAMME TV	0	0	00	3	1	0	00	00	0	0000000000	00	
N0024794	N0024794	====NZqT	13/10/2015	07:00:05:00	00:00:00:00	00:00:30:00	TITRE2 DU PROGRAMME TV	TITRE2 DU PROGRAMME TV	0	1	00	3	1	0	00	00	0	0000000000	00	
Fichier de sortie :

Code : Tout sélectionner

//fs0/clip.dir/N0132313	07:00:00:00	07:00:00:00				hard	TITRE DU PROGRAMME TV	0	00:00:00:00
//fs0/clip.dir/N0024794	07:00:05:00	07:00:05:00	00:00:30:00			auto	TITRE2 DU PROGRAMME TV	0	00:00:00:00
Pourquoi hard et/ou auto ?
En fait, ce programme va scruter un dossier tous les X secondes (partie watchfolder). Dès qu'un (ou plusieurs) fichier est présent il va prendre le dernier fichier crée pour le traiter.
Ce sont des playlist de fichier vidéo pour des chaînes de TV, 1 ligne = un programme TV.
Le "hard" signifie que le fichier ce lancera par action humaine de l'opérateur.
En "auto", les programmes ce lanceront à la suite sans actions humaine.

J'espère avoir été clair... :roll:

@Spock : Je vais essayé car en effet, il m'est arrivé deux ou trois fois d'ouvrir un fichier de sortie vide (je le ferme et quand le ré-ouvre tout vas bien).
@Mesa et @Ar-S : J’essaie ça cet après-midi :)

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 11:16
par djes
C'est déjà bien, mais je vois aussi que tu galères avec le "If..EndIf" à la mode Purebasic. En fait c'est tellement simple que ça parait compliqué. Tu devrais peut-être relire la doc : http://www.purebasic.com/french/documen ... endif.html
En tous cas, tu verras que tu as bien choisi, je me sers aussi de PB assez souvent pour le parsing de fichiers, c'est une de ses spécialités :)

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 11:56
par Marc56
Si je résume:

Code : Tout sélectionner

Exemple fichier entrée:
N0023313   N0132313   ====NZqU   13/10/2015   07:00:00:00   00:00:00:00   00:00:05:00   TITRE DU PROGRAMME TV   TITRE DU PROGRAMME TV   0   0   00   3   1   0   00   00   0   0000000000   00   
N0024794   N0024794   ====NZqT   13/10/2015   07:00:05:00   00:00:00:00   00:00:30:00   TITRE2 DU PROGRAMME TV   TITRE2 DU PROGRAMME TV   0   1   00   3   1   0   00   00   0   0000000000   00   

Exemple fichier sortie:
//fs0/clip.dir/N0132313   07:00:00:00   07:00:00:00            hard   TITRE DU PROGRAMME TV   0   00:00:00:00
//fs0/clip.dir/N0024794   07:00:05:00   07:00:05:00   00:00:30:00         auto   TITRE2 DU PROGRAMME TV   0   00:00:00:00


Structure en entrée ('+' = garder '-' = ignorer)
1 + ID
2 - (ignorer)
3 - (ignorer) 
4 - (ignorer) 
5 + Heure de début
6 - (ignorer) 
7 + Durée
8 + Titre
9 + Sommaire
(ignorer le reste)


Structure en sortie (//fs0/clip.dir/ est le prefixe du nom UNC du fichier de sortie ?)
1. //fs0/clip.dir/ + ID (champs 1)
2. Heure de début (champs 5)
3. Durée (champs 7)
4. écrire "hard" si première ligne, sinon champs 7)
5. Titre (champs 8)
6. Sommaire (champ 9)
En entrée comme en sortie, TAB (chr(9)) est le séparateur de champs.

C'est cela ?

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 12:48
par ballow
Marc56 a écrit :Si je résume:

Code : Tout sélectionner

Exemple fichier entrée:
N0023313   N0132313   ====NZqU   13/10/2015   07:00:00:00   00:00:00:00   00:00:05:00   TITRE DU PROGRAMME TV   TITRE DU PROGRAMME TV   0   0   00   3   1   0   00   00   0   0000000000   00   
N0024794   N0024794   ====NZqT   13/10/2015   07:00:05:00   00:00:00:00   00:00:30:00   TITRE2 DU PROGRAMME TV   TITRE2 DU PROGRAMME TV   0   1   00   3   1   0   00   00   0   0000000000   00   

Exemple fichier sortie:
//fs0/clip.dir/N0132313   07:00:00:00   07:00:00:00            hard   TITRE DU PROGRAMME TV   0   00:00:00:00
//fs0/clip.dir/N0024794   07:00:05:00   07:00:05:00   00:00:30:00         auto   TITRE2 DU PROGRAMME TV   0   00:00:00:00


Structure en entrée ('+' = garder '-' = ignorer)
1 + ID
2 - (ignorer)
3 - (ignorer) 
4 - (ignorer) 
5 + Heure de début
6 - (ignorer) 
7 + Durée
8 + Titre
9 + Sommaire
(ignorer le reste)


Structure en sortie (//fs0/clip.dir/ est le prefixe du nom UNC du fichier de sortie ?)
1. //fs0/clip.dir/ + ID (champs 1)
2. Heure de début (champs 5)
3. Durée (champs 7)
4. écrire "hard" si première ligne, sinon champs 7)
5. Titre (champs 8)
6. Sommaire (champ 9)
En entrée comme en sortie, TAB (chr(9)) est le séparateur de champs.

C'est cela ?
C'est presque ça :) :

1. //fs0/clip.dir/ + ID (champs 1) (//fs0/clip.dir/ est une valeur rentrée manuellement dans une box dans l'IHM)
2. Heure de début (champs 5)
3. Heure de début (champs 5) (Oui, il y a deux fois le champs 5)
4. Durée (champs 7) (ce champs ne doit pas apparaitre sur la première ligne)
5. écrire "hard" si première ligne, sinon champs 7)
6. Titre (champs 8 )
7. 0 (valeur codée en dur, ce sera toujours 0)
8. SOM (champs 6) qui signifie : Start Of Media. C'est le timecode de début du fichier vidéo, ici les fichiers commencent tous à 00:00:00:00)

Oui, dans tous les cas, TAB (chr(9)) est le séparateur de champs.

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 13:00
par ballow
Mesa a écrit :Ce code me parait incorrect:

Code : Tout sélectionner

If PtTableau=0 ;type$ = "auto"                      ; Si ligne 1 mettre "hard" et sur les autres "auto"
Else type$ = ("hard")
EndIf
If PtTableau>0
Else type$ = ("auto")
EndIf
Si tu le remplaces par celui-ci, ça va mieux ?

Code : Tout sélectionner

If PtTableau=0 ; Si ligne 1 mettre "hard" et sur les autres "auto"
type$ = ("hard")
Else 
type$ = ("auto")
EndIf
M.

Dans ce cas, j'ai "Hard" sur toute les lignes :?

Ce que d'ailleurs je ne comprend pas du tout... La commande est claire pourtant... Le problème viendrait de

Code : Tout sélectionner

PtTableau
??

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 14:23
par Marc56
Proposition:

Code : Tout sélectionner

EnableExplicit

ShowDebugOutput()

Enumeration 
    #handle_Fichier_IN
    #handle_Fichier_OUT
EndEnumeration

Global Fichier_IN.s     = GetCurrentDirectory() + "Fichier_IN.plt"
Global Fichier_OUT.s    = GetCurrentDirectory() + "Fichier_OUT.plt"
Global Read_Line.s, Write_Line.s
Global i
Global C1.s, C2.s, C3.s, C4.s, C5.s, C6.s, C7.s, C8.s
Global Read_Line.s

; -- Pour test
If FileSize(Fichier_OUT)
    Debug "Fichier exist: Delete"
    DeleteFile(Fichier_OUT)
EndIf


If Not ReadFile(#handle_Fichier_IN, Fichier_IN) 
    Debug "Le Fichier Source n'existe pas"
    Else 
    Debug "OK, fichier source existe"
    CreateFile(#handle_Fichier_OUT, Fichier_OUT, #PB_Ascii)
    
    Debug "Ok, Fichier destination disponible"
    
    While Not Eof(#handle_Fichier_IN)
        Read_Line = ReadString(#handle_Fichier_IN)

        C1 = "//fs0/clip.dir/" + StringField(Read_Line, 1, Chr(9)) ; après ce sera GetGadgetText(#champs) + StringField(Read_Line, 1, Chr(9))
        C2 = StringField(Read_Line, 5, Chr(9))
        C3 = C2
        If i = 0 
            C4 = ""     
        Else 
            C4 = StringField(Read_Line, 7, Chr(9))   
        EndIf
        If i = 0
            C5 = "hard"
        Else 
            C5 = "auto"
        EndIf
        C6 = StringField(Read_Line, 8, Chr(9))
        C7 = "0"
        C8 = StringField(Read_Line, 6, Chr(9))
        
        i + 1
        Debug i
        ; écriture
        Write_Line = C1 + Chr(9) + C2 + Chr(9) + C3 + Chr(9) + C4 + Chr(9) + C5 + Chr(9) + C6 + Chr(9) + C7 + Chr(9) + C8 + Chr(13)
        WriteString(#handle_Fichier_OUT, Write_Line)
    Wend
    
    CloseFile(#handle_Fichier_IN)
    CloseFile(#handle_Fichier_OUT)
EndIf

End
Au début ça ne marchait pas, car l'exemple en copié/collé avait mis 3 espaces à la place des tab :?
Le compteur 'i' qui s'incrémente après ne sert qu'à repérer facilement la ligne 0
Ce n'est pas du code très optimisé, c'est juste fait pour être didactique.

:)

Re: Conversion de fichier texte

Publié : jeu. 28/janv./2016 14:34
par Marc56
Spock a écrit :pour eviter le Chr(13)
utilise WriteStringN ;)
Oui bien, excellent, je l'oublie toujours :!:
(il faut que je relise la bibliothèque string)

Re: Conversion de fichier texte

Publié : ven. 05/févr./2016 14:53
par ballow
@Marc56, merci beaucoup pour ta proposition !

Ayant été absent quelques jours, c'est hier que j'ai commencé à regarder tout ça :)
J'ai donc adapté le code mais toutes les lignes sont formatté comme la premières... On dirait qu'il ne prend pas en compte " i ".

Code : Tout sélectionner

              If i = 0
                Duration$ = ""
              Else
                Duration$ = StringField(Texte$, 7, Chr(9)) ; On isole la durée du media on ne le met pas sur la première ligne !
              EndIf
              
              If i = 0
                type$ = "hard"
              Else 
                type$ = "auto"
              EndIf
On dirait que pour lui, " i " est toujours égal à 0. Question super bête mais " i " est-elle une constante ? Est-on obligé de lui dire que " i " = numéro de ligne ?

Re: Conversion de fichier texte

Publié : ven. 05/févr./2016 14:58
par Ar-S
donne ta boucle complète.

Ton if i = etc..
endif

doit être dans une boucle for i = mahin to truc sinon ton i ne s'incrémentera pas.