Enregistrer un tableau de chaînes
Enregistrer un tableau de chaînes
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) ?
Dans un fichier texte ou un fichier binaire ?
Peu importe les deux méthodes :
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 :
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
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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
À 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
A+
Guimauve
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:
Exemple:
Voici aussi 2 autres fonctions utiles (mais pas efficace pour les petites chaînes) pour stocker un tableau de chaînes dans un PackFile :/!\ 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).
@+
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
Code : Tout sélectionner
Dim x.S(1999)
Debug "Il y a " + Str(MaxOf(x() ) ) + " chaînes allouées pour le tableau x()"
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 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).
@+