Page 1 sur 1

Enregistrer un tableau de chaînes

Publié : dim. 29/juil./2007 21:43
par Ollivier
Quelqu'un a-t-il une méthode pour enregistrer un tableau de chaînes dans un fichier de la même manière qu'une simple chaîne (WriteString) ?

Publié : lun. 30/juil./2007 0:53
par Guimauve
Dans un fichier texte ou un fichier binaire ?

Peu importe les deux méthodes :

Code : Tout sélectionner

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Sauvegarde d'un tableau de chaine de caratère.
; Fichier : Démonstration
; Version : 1.0.0
; Programmation : OK
; Programmé par : Guimauve
; Date : 29-07-2007
; Mise à jour : 29-07-2007
; Codé avec PureBasic V4.10
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Dim Liste.s(10)

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Initialisation du tableau

Debug "Initialisation du tableau"
Debug ""

For Index = 0 To 10
  Liste(Index) = "Allô le monde ! No." + Str(Index)
Next

For Index = 0 To 10
  Debug Liste(Index)
Next

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Création du fichier format texte

Debug ""
Debug "Création du fichier format texte"
Debug ""

If CreateFile(0, "Fichier texte.txt")
  
  For Index = 0 To 10
    WriteStringN(0, Liste(Index))
  Next
  
  CloseFile(0)
  
EndIf

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Création du fichier format binaire

Debug "Création du fichier format binaire"
Debug ""

If CreateFile(1, "Fichier binaire.bin")
  
  For Index = 0 To 10
    WriteLong(1, Len(Liste(Index)))
    WriteData(1, @Liste(Index), Len(Liste(Index)))
  Next
  
  CloseFile(1)
  
EndIf



; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Initialisation du tableau

Debug "Remise à zéro du tableau"
Debug ""

For Index = 0 To 10
  Liste(Index) = ""
Next

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Lecture du fichier format texte

Debug "Lecture du fichier format texte"
Debug ""

If ReadFile(0, "Fichier texte.txt")
  
  For Index = 0 To 10
    Liste(Index) = ReadString(0)
  Next
  
  CloseFile(0)
  
EndIf

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Visualisation du tableau

Debug "Le tableau depuis le fichier texte"
Debug ""

For Index = 0 To 10
  Debug Liste(Index)
Next

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Initialisation du tableau

Debug ""
Debug "Remise à zéro du tableau"
Debug ""

For Index = 0 To 10
  Liste(Index) = ""
Next

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Lecture du fichier format binaire

Debug "Lecture du fichier format binaire"
Debug ""

If ReadFile(1, "Fichier binaire.bin")
  
  For Index = 0 To 10
    
    Len = ReadLong(1)
    Liste(Index) = Space(Len)
    ReadData(1, @Liste(Index), Len)
  Next
  
  CloseFile(1)
  
EndIf

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Visualisation du tableau

Debug "Le tableau depuis le fichier binaire"
Debug ""

For Index = 0 To 10
  Debug Liste(Index)
Next

; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Comme une seule chaîne ce n'est pas possible à moins de concaténer toute les chaines les unes à la suites des autres. Mais comment les récupérer plus tard ???

À moins de faire :

Code : Tout sélectionner

Dim Liste.s(10)

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Initialisation du tableau

Debug "Initialisation du tableau"
Debug ""

For Index = 0 To 10
  Liste(Index) = "Allô le monde ! No." + Str(Index)
Next

For Index = 0 To 10
  Total.s = Total + Liste(Index) + " | "
Next

Debug Total 
pour avoir une seule chaine à écrire. Et à la lecture on compte le nombre de "|" et avec stringfield on découpe chaque index et on le met en place dans le tableau mais ça me semble compliqué pour rien. Je préfaire la méthode que j'ai donnée plus haut.

A+
Guimauve

Publié : mar. 31/juil./2007 5:33
par Ollivier
Merci Guimauve pour ta réponse.

En parallèle, j'ai fait quelques recherches sur la manière dont les tableaux sont implantés dans la mémoire.

Je voulais savoir alors si les chaînes d'un même tableau se 'touchaient' les unes aux autres pour enregistrer tout d'un seul coup (ta 2ème méthode).
>> Hélas NON! Pas tout le temps

Les chaînes sont stockées par quads (groupes de 8 octets). Donc ta 1ère méthode (enregistrement chaîne après chaîne) est la seule méthode.

J'ai néanmoins découvert un truc sympa en fouinant la mémoire. J'en ai fait une procédure. Elle permet de retourner le nombre total de chaînes allouées dans un tableau à 1 dimension:

Code : Tout sélectionner

Procedure.L MaxOf(Tmp.S(1) )
  Max.L = PeekL(@Tmp() - 8) - 1
  ProcedureReturn Max
EndProcedure
Exemple:

Code : Tout sélectionner

Dim x.S(1999)
Debug "Il y a " + Str(MaxOf(x() ) ) + " chaînes allouées pour le tableau x()"
Voici aussi 2 autres fonctions utiles (mais pas efficace pour les petites chaînes) pour stocker un tableau de chaînes dans un PackFile :

Code : Tout sélectionner

Declare PackStringArray(Tmp.S(1) )
Declare UnpackStringArray(Tmp.S(1) )
Declare.L MaxOf(Tmp.S(1) )

Procedure PackStringArray(Tmp.S(1) )
  Max.L = MaxOf(Tmp() )
  AddPackMemory(@Max, 4, 9)
  For i = 0 To Max
    *Ptr = @Tmp(i)
    If *Ptr <> 0    
      AddPackMemory(*Ptr, Len(Tmp(i) ), 9)
    Else
      Tmp = 0      
      AddPackMemory(@Tmp, 4, 9)
    EndIf
  Next
EndProcedure

Procedure UnpackStringArray(Tmp.S(1) )
  *Tmp = NextPackFile()
  If PackFileSize() = 4
    ReDim Tmp.S(PeekL(*Tmp) )
    Max.L = MaxOf(Tmp() )
    For i = 0 To Max
      *Tmp = NextPackFile()
      Tmp(i) = Space(PackFileSize() )
      CopyMemory(*Tmp, @Tmp(i), Len(Tmp(i) ) )
    Next
  EndIf
EndProcedure

Procedure.L MaxOf(Tmp.S(1) )
  Max.L = PeekL(@Tmp() - 8) - 1
  ProcedureReturn Max
EndProcedure
/!\ Il faut ouvrir respectivement le fichier *.PAK avec CreatePack() pour l'écritute et OpenPack() pour la lecture. MaxOf() évite de renseigner la taille du tableau. Ce n'est pas plus mal.

Il n'y a pas besoin de gérer la taille du tableau quand on le charge depuis le fichier. UnpackStringArray() s'en occupe avec Redim. Il faut juste créer au préalable un tableau vide dans le style Dim Tableau.S(0).

@+