Variable structure et sauvegarde

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Variable structure et sauvegarde

Message par Kwai chang caine »

Bonjour

Peut on sauvegarder une variable structure avec une seule instruction ??

Code : Tout sélectionner

Structure Autorisations
 Logiciel.s
 Utilisateur.s
 Machine.s
EndStructure 

Acces.Autorisations

Acces\Logiciel = "1"
Acces\utilisateur = "2"
Acces\Machine = "3"

OpenFile(1,"c:\Essais.txt")
WriteLong(1,Acces) 
CloseFile(1)

Acces\Logiciel = ""
Acces\utilisateur = ""
Acces\Machine = ""

OpenFile(1,"c:\Essais.txt")
Acces =  ReadLong(1) 
CloseFile(1)
Ou bien est on obligé de sauvegarder chaque element de la structure les uns apres les autres ? :

Code : Tout sélectionner

Structure Autorisations
 Logiciel.s
 Utilisateur.s
 Machine.s
EndStructure 

Acces.Autorisations

Acces\Logiciel = "1"
Acces\utilisateur = "2"
Acces\Machine = "3"

OpenFile(1,"c:\Essais.txt")
WriteStringN(1,Acces\Logiciel) 
WriteStringN(1,Acces\utilisateur) 
WriteStringN(1,Acces\Machine) 
CloseFile(1)

Acces\Logiciel = ""
Acces\utilisateur = ""
Acces\Machine = ""

OpenFile(1,"c:\Essais.txt")
Acces\Logiciel = ReadString(1)
Acces\utilisateur = ReadString(1) 
Acces\Machine = ReadString(1)
CloseFile(1)
Merci
Bonne journée
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Il faut sauvegarder chaque élément de la structure !
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Merci Progi de ta réponse rapide 8)

Et pour les listes chainées, c'est pareil, ou bien existe t'il une instruction pour la sauvegarder d'un coup ?
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

C'est pareil !

Par contre, attends d'avoir une autre réponse pour confirmer mes dires !
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Merci bien et bonne journée à toi :wink:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

tu peux sauvegarder une structure dans un fichier dans certaines situations :

Code : Tout sélectionner

Structure Autorisations
  Logiciel.s{16}
  Utilisateur.s{16}
  Machine.s{16}
EndStructure 

Acces.Autorisations

Acces\Logiciel    = "MonLogiciel"
Acces\Utilisateur = "MonUtilisateur"
Acces\Machine     = "MaMachine" 

Debug @Acces\Logiciel
Debug @Acces\Utilisateur
Debug @Acces\Machine

If CreateFile(1,"c:\essais.txt")
  WriteData(1, @Acces, SizeOf(Autorisations))
  CloseFile(1) 
EndIf
Dernière modification par Flype le jeu. 23/nov./2006 15:19, modifié 4 fois.
Image
Dorian
Messages : 489
Inscription : mar. 15/mars/2005 15:33

Message par Dorian »

Merci Flype pour ton code. Celui-là va passer dans mes stock (pour le retrouver quand je serais bloqué ^^)
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

Flype ton astuce n'est l'idéal, tu donne une longueur fixe aux chaînes de caractères. Et si je te disais que les longueurs doivent rester variables alors ton astuce n'est plus valide.

Je me répète pour la x ième fois, quand vous avez une structure qui contient des chaînes de caractère qui doit être écrite dans un fichier binaire

ON DOIT TOUJOURS ÉCRIRE UN LONG POUR INDIQUER LA LONGUEUR DE LA CHAÎNE AVANT D'ÉCRIRE LE DATA DE LA CHAÎNE.

ENSUITE QUAND ON LIT DANS LE FICHIER, ON LIT UN LONG, AVEC SPACE ON INITIALISE LA CHAÎNE VIDE À LA BONNE LONGUEUR ET ON LIT LE DATA DE LA CHAÎNE.

Voiçi un exemple opérationnel.

A+
Guimauve

Code : Tout sélectionner

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; CODE GÉNÉRÉ AUTOMATIQUEMENT, NE PAS MODIFIER À
; MOINS D'AVOIR UNE RAISON TRÈS TRÈS VALABLE !!!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Déclaration de la Structure <<<<<

Structure Autorisations
   
   Logiciel.s
   Utilisateur.s
   Machine.s
   
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les mutateurs <<<<<

Macro SetAutorisationsLogiciel(AutorizeA, P_Logiciel)
   
   AutorizeA\Logiciel = P_Logiciel
   
EndMacro

Macro SetAutorisationsUtilisateur(AutorizeA, P_Utilisateur)
   
   AutorizeA\Utilisateur = P_Utilisateur
   
EndMacro

Macro SetAutorisationsMachine(AutorizeA, P_Machine)
   
   AutorizeA\Machine = P_Machine
   
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les observateurs <<<<<

Macro GetAutorisationsLogiciel(AutorizeA)
   
   AutorizeA\Logiciel
   
EndMacro

Macro GetAutorisationsUtilisateur(AutorizeA)
   
   AutorizeA\Utilisateur
   
EndMacro

Macro GetAutorisationsMachine(AutorizeA)
   
   AutorizeA\Machine
   
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Update <<<<<

Macro UpdateAutorisations(AutorizeA, P_Logiciel, P_Utilisateur, P_Machine)
   
   SetAutorisationsLogiciel(AutorizeA, P_Logiciel)
   SetAutorisationsUtilisateur(AutorizeA, P_Utilisateur)
   SetAutorisationsMachine(AutorizeA, P_Machine)
   
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Lecture fichier Binaire <<<<<

Procedure ReadAutorisations(FileID.l, *AutorizeA.Autorisations)
   
   SetAutorisationsLogiciel(*AutorizeA, Space(ReadLong(FileID)))
   ReadData(FileID, @GetAutorisationsLogiciel(*AutorizeA), Len(GetAutorisationsLogiciel(*AutorizeA)))
   SetAutorisationsUtilisateur(*AutorizeA, Space(ReadLong(FileID)))
   ReadData(FileID, @GetAutorisationsUtilisateur(*AutorizeA), Len(GetAutorisationsUtilisateur(*AutorizeA)))
   SetAutorisationsMachine(*AutorizeA, Space(ReadLong(FileID)))
   ReadData(FileID, @GetAutorisationsMachine(*AutorizeA), Len(GetAutorisationsMachine(*AutorizeA)))
   
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Écriture fichier Binaire <<<<<

Procedure WriteAutorisations(FileID.l, *AutorizeA.Autorisations)
   
   WriteLong(FileID, Len(GetAutorisationsLogiciel(*AutorizeA)))
   WriteData(FileID, @GetAutorisationsLogiciel(*AutorizeA), Len(GetAutorisationsLogiciel(*AutorizeA)))
   WriteLong(FileID, Len(GetAutorisationsUtilisateur(*AutorizeA)))
   WriteData(FileID, @GetAutorisationsUtilisateur(*AutorizeA), Len(GetAutorisationsUtilisateur(*AutorizeA)))
   WriteLong(FileID, Len(GetAutorisationsMachine(*AutorizeA)))
   WriteData(FileID, @GetAutorisationsMachine(*AutorizeA), Len(GetAutorisationsMachine(*AutorizeA)))
   
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Lecture d'une liste chaînée dans le fichier en cours <<<<<

Procedure ReadLinkedListOfAutorisations(FileID.l, LList.Autorisations())
   
  LIST_MAX = ReadLong(FileID)
   
   For Index = 1 To LIST_MAX
      AddElement(LList())
      ReadAutorisations(FileID, LList())
   Next
   
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Écriture d'une liste chaînée dans le fichier en cours <<<<<

Procedure WriteLinkedListOfAutorisations(FileID.l, LList.Autorisations())
   
   WriteLong(FileID, CountList(LList()))
   
   ForEach LList()
      WriteAutorisations(FileID, LList())
   Next
   
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Macro de déboguage <<<<<

Macro DebugAutorisations(AutorizeA)
   
   Debug GetAutorisationsLogiciel(AutorizeA)
   Debug GetAutorisationsUtilisateur(AutorizeA)
   Debug GetAutorisationsMachine(AutorizeA)
   
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code généré en : 00.031 secondes <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;/ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;/ <<<<< !!! ATTENTION - VOUS ÊTES MAINTENANT DANS UNE ZONE DE TEST - ATTENTION !!! <<<<<
;/ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

NewList Maliste.Autorisations()

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; On ajoute des éléments à la liste

AddElement(Maliste())
UpdateAutorisations(Maliste(), "PureBasic", "Fred", "Windows")

AddElement(Maliste())
UpdateAutorisations(Maliste(), "Visual Designer", "Darth Vador", "Mac OS")

AddElement(Maliste())
UpdateAutorisations(Maliste(), "MS Word", "Abraham Lincolm", "Windows")

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; On regarde ce que ça donne

Debug "On regarde ce que ça donne"

ForEach Maliste()
   
   Debug "-------------------------------------------"
   DebugAutorisations(Maliste())

Next

Debug "-------------------------------------------"

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; On enregistre la liste dans un fichier binaire

Debug "On enregistre la liste dans un fichier binaire"

If CreateFile(0, "Mon fichier binaire.dat")
   
   WriteLinkedListOfAutorisations(0, Maliste())
   
   CloseFile(0)
Else 
   MessageRequester("Erreur", "Impossible de créer le fichier !")
EndIf

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; On vide la liste

Debug "On vide la liste"

ClearList(Maliste())

Debug CountList(Maliste())

Debug "-------------------------------------------"

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; On lit la liste dans un fichier binaire

Debug "On lit la liste dans un fichier binaire"

If OpenFile(1, "Mon fichier binaire.dat")
   
   ReadLinkedListOfAutorisations(1, Maliste())
   
   CloseFile(1)
Else 
   MessageRequester("Erreur", "Impossible de lire le fichier !")
EndIf

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; On regarde ce que ça donne

Debug "On regarde ce que ça donne depuis la lecture"
Debug "du fichier binaire"

ForEach Maliste()
   
   Debug "-------------------------------------------"
   DebugAutorisations(Maliste())
   
Next

Debug "-------------------------------------------"

; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

ah et j'oubliais - enregistrer les données c'est sympa que si on peut les recharger. donc voici un source plus complet :

Code : Tout sélectionner

; Example de persistence des données dans une structure
; PureBasic4.0 - flype - 2006.


; Définition de la structure 'persistente'

Structure Autorisations
  Version.l
  Logiciel.s{32}
  Utilisateur.s{32}
  Machine.s{32}
  MotDePasse.c[8]
EndStructure 

Acces.Autorisations


; On définit des valeurs pour la variable 'Acces'

Acces\Version     = 123456
Acces\Logiciel    = "MonLogiciel"
Acces\Utilisateur = "MonUtilisateur"
Acces\Machine     = "MaMachine" 
PokeS(@Acces\MotDePasse, "A0B1C2D3")


; On enregistre la variable 'Acces' et ses champs dans un fichier

If CreateFile(1,"c:\essais.txt")
  WriteData(1, @Acces, SizeOf(Autorisations))
  CloseFile(1) 
EndIf


; On remet à Zéro la variable 'Acces'

Acces\Version     = #Null
Acces\Logiciel    = #Null$
Acces\Utilisateur = #Null$
Acces\Machine     = #Null$
PokeS(@Acces\MotDePasse, #Null$)


; On recharge dans la variable 'Acces' les données enregistrées dans le fichier

If ReadFile(1,"c:\essais.txt") 
  ReadData(1, @Acces, SizeOf(Autorisations)) 
  CloseFile(1) 
EndIf 


; Pour preuve, les données sont bien remontées malgré la remise à zéro (ligne 34).

Debug Acces\Version
Debug Acces\Logiciel
Debug Acces\Utilisateur
Debug Acces\Machine
Debug PeekS(@Acces\MotDePasse, 8)

:)


Bon sinon il faut comprendre en fait que seuls les chaines de caractères '.s' ou '$' ne peuvent pas être enregistrées de cette façon puisqu'elles sont allouées dynamiquement en mémoire. Seul le pointeur de la chaine serait enregistré ce qui n'a aucun intérêt. Par contre avec des chaines 'fixes' ( champs.s{NbOctets} ) comme on a vu c'est OK. Mais ca fonctionne aussi avec des types de données plus classiques.
Image
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

@Guimauve

ok d'accord, tu es prié de modérer tes propos.

qu'est ce que j'ai écris ici en avertissement ?
tu peux sauvegarder une structure dans un fichier dans certaines situations.
alors t'es gentil mais même si tu as raison, la question est de savoir si on peut enregistrer une structure dans un fichier en une ligne ou deux. la réponse est que dans la plupart des cas c'est NON, maintenant si on fait attention à ce qu'on fait, cela ne pose AUCUN problème !

une chaine de caractères est certes variables mais la longueur des données est souvent fixée à un maximum.

Enfin faite comme vous voulez - apprenez à maitriser différentes situations - j'en ai montré une - Guimauve en montre une autre - çà fait 2 méthodes. très bien.
Image
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

ON DOIT TOUJOURS ÉCRIRE UN LONG POUR INDIQUER LA LONGUEUR DE LA CHAÎNE AVANT D'ÉCRIRE LE DATA DE LA CHAÎNE.

ENSUITE QUAND ON LIT DANS LE FICHIER, ON LIT UN LONG, AVEC SPACE ON INITIALISE LA CHAÎNE VIDE À LA BONNE LONGUEUR ET ON LIT LE DATA DE LA CHAÎNE.
en plus, excuse moi mais c'est faux.

d'où tu postule que TA façon c'est la SEULE viable - cà fait un peu dictat ta façon de parler au gens, non ?

et si je n'ai pas envie d'écrire un LONG avant ma chaîne ?
je peux - il y a d'autres méthodes. Le caractère 0 de fin de chaines est aussi une autre méthode.
Image
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

moi ca que je ne comprends pas , c'est pourquoi il n'est pas fait allusion dans la Doc de ce genre d'écriture

Code : Tout sélectionner

 Logiciel.s{32} 
je ne savais même pas que cela existais !! 8O

pareil , pas trouvé d'info dans la Doc , sur les Structures a propos des tableaux Static !! :?

Code : Tout sélectionner

Logiciel.s[32] 
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

C'est vrai que j'y suis peut-être aller un peu fort, veuillez m'excuser.

Sauf que regarde bien ce qui arrive pendant la vie d'un programme

Le programme en question utilise cette Structure :

Code : Tout sélectionner

Structure Autorisations
  Logiciel.s{16}
  Utilisateur.s{16}
  Machine.s{16}
EndStructure 
Après 2 ans d'utilisation, et probablement beaucoup de donnée d'enregistré, genre 200 Go, la structure doit être modifié pour celle-ci

Code : Tout sélectionner

Structure Autorisations
  Logiciel.s{32}
  Utilisateur.s{64}
  Machine.s{32}
EndStructure 
Là si tu n'as pas écrit la longueur de la chaîne ça va vraiment être le bordel de charger les données des 2 versions avec le même système.
en plus, excuse moi mais c'est faux.

d'où tu postule que TA façon c'est la SEULE viable - cà fait un peu dictat ta façon de parler au gens, non ?

et si je n'ai pas envie d'écrire un LONG avant ma chaîne ?
je peux - il y a d'autres méthodes. Le caractère 0 de fin de chaines est aussi une autre méthode.
Je ne dis pas que c'est la seule méthode viable, ce que je dis c'est que c'est la méthode que semble être la plus robuste. Dans le cas de cette structure c'est facile tout les types sont identiques, parcontre si les types sont variés (.b, .c, .w, .l, .f, .q, .d) et des types utilisateurs en même temps dans la même structure, trouver le caractère de fin de chaîne semble est difficile voir peut-être même impossible.

Ma manière de programmer est très rigide certe, mais je dirais que depuis que fais les choses de cette manière, le temps de débogguage est réduit de 80 à 90% et les programmes sont bien plus stables.

Mais le plus important, ma méthode n'engage personne.

@Flype - Pour le message précédent, j'aurais pu mettre la font à 18, en gras et en rouge, mais je l'ai pas fais.

Guimauve
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

@Guimauve

je répète que tu as raison et je saisis parfaitement ce que tu veux dire :) .
je suis moi même développeur de softs (pour l'entreprise où je travaille). Mes logiciels ont pour certains déjà 3ans d'age, d'autres 2ans, d'autres tout récents. Et, oui, penser à l'évolutivité ( en plus de la compatibilité ) des programmes est quelque chose qui me vient à l'esprit au quotidien, du coup.
J'ai beaucoup de données aussi à stocker et il n'est pas rare que ces données doivent évoluer. Des moulinettes, j'en ai codées... Ceci dit, ma tache est simplifié énormément par l'utilisation de base de données (mysql ou postgres) via les commandes database de purebasic.

l'objectif que j'avais au travers de mon exemple n'était pas d'imposer ou meme de conseiller une facon de faire mais juste de montrer que c'est possible de sauvegarder une structure - brute de pommes - dans un fichier. si, bien sûr, la structure s'y prête et que l'on a une bonne raison de faire comme çà. On peut programmer sérieusement et parfois s'amuser avec des codes un peu exotiques du moment qu'on sait ce qu'on fait.

j'ai eu des cas en programmant des périphériques (toujours pour l'entreprise où je bosse) où j'ai dû codé comme çà parce que c'etait les recommandations du constructeurs (API en C)... et j'ai découvert à ce moment que c'était possible de le faire en PureBasic alors je partage mon savoir sur ce point précis.


@dobro
les string.s{taille} sont dans la documentation purebasic
CHM -> Variables, Types et Opérateurs -> Tableau Types basiques -> Dernière ligne.

OK, je te l'accorde la doc n'explique vraiment pas comment s'en servir ni à quoi ca sert. Cette fonctionnalité est arrivé avec PB4.0 et ca été évoqué quelquefois déjà je pense sur ce forum et beaucoup sur le forum officiel.

Attention ce type de String n'est pas terminé par un 0 comme les chaines classiques. Par contre çà c'est dans la doc (Ouf).

[EDIT]
c'est d'ailleurs pour cette raison précise (chaine non terminée par zéro)
que la dernière ligne de mon exemple est :
Debug PeekS(@Acces\MotDePasse, 8)
Dernière modification par Flype le jeu. 23/nov./2006 20:50, modifié 2 fois.
Image
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Alors la !!!!!!on peux dire que j'ai eu une reponse :lol:

Moi qui dab est 300 visites et jamais de solutions, j'suis ébourrifé :lol:

Je vous remercie tous pour votre aide. 8)
Passez une excelente soirée
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre