OVH Cloud OVH Cloud

le C++ et la gestion des fichiers

6 réponses
Avatar
Don Miguel
Bonjour.
Je me suis dernièrement lancé dans l'adaptation d'un petit jeu calculette
sur PC.
J'essaie donc de profiter de cette occasion pour passer du C au C++.
Dans ce jeu, il me serait pratique de pouvoir avoir certaines données
sauvegardées dans un fichier.
J'utilise la librairie Allegro, qui inclut des fonctions permettant
d'utiliser les fichiers très proches des fread, fopen, fwrite... de stdio.h
Voilà où je veux en venir: Peut-on stocker des objets dans un fichier de la
meme manière que n'importe quelle variable en C?
Merci d'avance
Mickael

6 réponses

Avatar
espie
In article <3fb0bac0$0$27029$,
Don Miguel wrote:
Voilà où je veux en venir: Peut-on stocker des objets dans un fichier de la
meme manière que n'importe quelle variable en C?


Oui.

On ne peut dans aucun des deux cas.

Ca a en general autant de sens de stocker un objet dans un fichier que
de stocker un pointeur dans un fichier.

Le probleme a meme un nom: ca s'appelle la serialisation. Et c'est pas
du tout un probleme simple. Independamment de petits problemes
d'architecture de la machine (endianess, format des flottants), des qu'on
a quoi que ce soit qui contient un pointeur, de maniere visible ou
invisible, c'est pas facile a stocker dans un fichier.

Le C++ vient (en partie) a la rescousse en permettant de definir des
operations d'entrees/sorties pour chaque type de donnees... mais ca ne
rend pas la definition-meme de ces operations plus simples pour autant !

Avatar
Pierre Maurette
"Don Miguel" a écrit
Bonjour.
Je me suis dernièrement lancé dans l'adaptation d'un petit jeu calculette
sur PC.
J'essaie donc de profiter de cette occasion pour passer du C au C++.
Dans ce jeu, il me serait pratique de pouvoir avoir certaines données
sauvegardées dans un fichier.
J'utilise la librairie Allegro, qui inclut des fonctions permettant
d'utiliser les fichiers très proches des fread, fopen, fwrite... de
stdio.h

Voilà où je veux en venir: Peut-on stocker des objets dans un fichier de
la

meme manière que n'importe quelle variable en C?
Non.

Vous pourriez articuler votre démarche comme ça :
Fortement inspiré des fichiers ini de Windows, un fichier texte de ce genre:

<jeu.ini>
[general]
Top@
LeftE6
DepuisDate/11/03
DepuisHeure:17:46
joueur1=Petrus
joueur2ºcchus
joueur3 joueur4
[Petrus]
ScoreCourantu
ScoreMax2

[Bacchus]
ScoreCourantQ
ScoreMax2
<jeu.ini>
Vous choisissez les séparateurs à votre convenance.
Les mots entre [] définissent ici 3 sections.
Vous pourriez simplifier en gérant 3 fichiers texte (general.ini,
petrus.sav, bacchus.sav par exemple), et pas de sections.
Ce ou ces fichiers sont considérés comme créés par l'appli, ce qui simplifie
beaucoup le parsing et la gestion d'erreur.
Pour créer ces fichiers, lire ou écrire dedans, j'utilise la classe TIniFile
de la VCL Borland. Vous pouvez vous en inspirer sans tout implémenter, ce
n'est pas bien compliqué à partir du moment où vous savez manipuler des
fichiers texte ligne par ligne.
Pour info :
Une seule propriété : FileName
Quelques méthodes :
ReadInteger(Section, NomParam, ValDefaut)
WriteInteger(Section, NomParam, Valeur)
On trouve aussi, par exemple, ReadString(), ReadBool(), ReadFloat(), et les
Write correspondant et bien d'autres comme ValueExists() et SectionExists().
Quelques méthodes également pour la gestion des sections. Pour votre
problème, une demi-douzaine de méthodes doivent suffire.
Ce genre de classe existe certainement dans de nombreuses bibliothèques (la
votre ?).

Une fois ce point réglé, le reste coule tout seul : dans les classes dont
vous souhaitiez sauver des instances, par exemple UnJoueur, vous ajoutez
deux méthodes : SaveScores() et RestoreScore(), qui utilisent une instance
temporaire de TIniFile.
Bien entendu, dans le pseudo exemple que je donne, vous avez créé autant
d'instances de UnJoueur que de NomJoueur récupérés à l'aide de TIniFile.

Cordialement,

Pierre

Avatar
kanze
"Pierre Maurette" wrote in message
news:<3fb122b9$0$250$...
"Don Miguel" a écrit

Je me suis dernièrement lancé dans l'adaptation d'un petit jeu
calculette sur PC. J'essaie donc de profiter de cette occasion pour
passer du C au C++. Dans ce jeu, il me serait pratique de pouvoir
avoir certaines données sauvegardées dans un fichier. J'utilise la
librairie Allegro, qui inclut des fonctions permettant d'utiliser
les fichiers très proches des fread, fopen, fwrite... de stdio.h
Voilà où je veux en venir: Peut-on stocker des objets dans un
fichier de la meme manière que n'importe quelle variable en C?


Non. Vous pourriez articuler votre démarche comme ça : Fortement
inspiré des fichiers ini de Windows, un fichier texte de ce genre:


C'est un peu la marteau pilon pour écraser la mouche, non ? Pourquoi pas
carrément XML, alors, si on tient réelement à la complexité. (Ce n'est
pas pour dire que ta solution ne convient jamais. Mais avant qu'il en
soit là...)

Son problème, tel que je l'ai compris, c'est de la persistance, toute
bête.

<jeu.ini>
[general]
Top@
LeftE6
DepuisDate/11/03
DepuisHeure:17:46
joueur1=Petrus
joueur2ºcchus
joueur3 > joueur4 >
[Petrus]
ScoreCourantu
ScoreMax2

[Bacchus]
ScoreCourantQ
ScoreMax2
<jeu.ini>

Vous choisissez les séparateurs à votre convenance. Les mots entre []
définissent ici 3 sections. Vous pourriez simplifier en gérant 3
fichiers texte (general.ini, petrus.sav, bacchus.sav par exemple), et
pas de sections.


C'est la solution habituelle sous Unix. Avec un répertoire pour
l'application, et un fichier par section. Le cas échéant, les fichiers
peuvent avoir des formats différents.

Je ne sais pas ce qui est plus facile pour l'utilisateur. Il y a des
pour et des contre dans les deux cas.

Ce ou ces fichiers sont considérés comme créés par l'appli, ce qui
simplifie beaucoup le parsing et la gestion d'erreur.


L'intérêt d'un fichier de configuration, c'est précisement que
l'utilisateur peut l'éditer.

Et ce n'est pas parce que le fichier est écrit par le programme qu'on
peut supposer qu'il a un format correct. Tout au plus peut-on être plus
brutal dans le traitement d'erreur.

Pour créer ces fichiers, lire ou écrire dedans, j'utilise la classe
TIniFile de la VCL Borland. Vous pouvez vous en inspirer sans tout
implémenter, ce n'est pas bien compliqué à partir du moment où vous
savez manipuler des fichiers texte ligne par ligne.


J'ai bien implémenté des classes de gestion de la configuration qui
lisent de tels fichiers. Je n'ai jamais choisi ce format quand c'est le
programme qui doit les écrire.

Pour info :
Une seule propriété : FileName


C'est un paramètre dans la ligne de commande, non ?

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Pierre Maurette
a écrit
[...]
C'est un peu la marteau pilon pour écraser la mouche, non ? Pourquoi pas
carrément XML, alors, si on tient réelement à la complexité. (Ce n'est
pas pour dire que ta solution ne convient jamais. Mais avant qu'il en
soit là...)

Son problème, tel que je l'ai compris, c'est de la persistance, toute
bête.
Je voulais surtout signifier que l'objet devait se sauver et se restaurer

lui-même. Dans mon idée, les méthodes SaveScores() et RestoreScores()
n'existent pas, ce sont respectivement le destructeur et le constructeur
(qui nécessite au moins une ID d'instance, le nom du joueur dans l'exemple,
en paramètre).
Les ID d'instance sont elle-mêmes récupérées et sauvées par l'appli.
Et comme je disposais de TIniFile ...
Ça me suggère d'ailleurs d'en "cloner" une version simplifiée et portable.

L'intérêt d'un fichier de configuration, c'est précisement que
l'utilisateur peut l'éditer.
tout à fait. L'éditer et surtout le lire.

En fait, dans la VCL, TIniFile descend de TCustomIniFile, tout comme
TRegistryIniFile. De cette façon, on peut travailler en mode "ficier .ini"
et ensuite (éventuellement) passer en mode "registre système".

J'ai bien implémenté des classes de gestion de la configuration qui
lisent de tels fichiers. Je n'ai jamais choisi ce format quand c'est le
programme qui doit les écrire.
C'est un format Windows. Mais rien n'interdit de le réutiliser.


Pour info :
Une seule propriété : FileName


C'est un paramètre dans la ligne de commande, non ?
La propriété FileName est le nom complet du fichier INI, pas de l'appli.

TIniFile représente un fichier INI.

Cordialement,
Pierre


Avatar
kanze
"Pierre Maurette" wrote in message
news:<3fb1f916$0$257$...
a écrit
[...]
C'est un peu la marteau pilon pour écraser la mouche, non ? Pourquoi
pas carrément XML, alors, si on tient réelement à la complexité. (Ce
n'est pas pour dire que ta solution ne convient jamais. Mais avant
qu'il en soit là...)

Son problème, tel que je l'ai compris, c'est de la persistance, toute
bête.


Je voulais surtout signifier que l'objet devait se sauver et se
restaurer lui-même.


Mais tu as parlé surtout d'un format particulier.

Dans beaucoup de cas, on utilise un format binaire pour la persistance
(bien que personnellement, le deboggage est beaucoup plus simple avec du
texte). Dans le cas d'un format texte, on recherche en général un format
extrèmement simple à parser. La classe connaît son format ; il suffit
donc de simplement écrire les valeurs, avec un séparateur. Pas besoin
des clés, etc.

Sinon, pour quelque chose hièrarchiquement structurée, comme une classe,
j'aurais tendance à penser que quelque chose comme l'XML est plus
adapte. Ton format a exactement two niveaux : les sections, et les
entrées. Ça ne correspond pas à une classe en C++.

Dans mon idée, les méthodes SaveScores() et RestoreScores() n'existent
pas, ce sont respectivement le destructeur et le constructeur (qui
nécessite au moins une ID d'instance, le nom du joueur dans l'exemple,
en paramètre).


C'est une des possibilités, en effet. En revanche, je le vois mal avec
le format que tu préconcises.

Les ID d'instance sont elle-mêmes récupérées et sauvées par l'appli.
Et comme je disposais de TIniFile ... Ça me suggère d'ailleurs d'en
"cloner" une version simplifiée et portable.

L'intérêt d'un fichier de configuration, c'est précisement que
l'utilisateur peut l'éditer.


tout à fait. L'éditer et surtout le lire.


La lecture est importante toujours, ne serait-ce que pour la mise au
point. Chaque fois que je me suis trouvé à travailler avec des fichiers
binaires, une des premières choses qu'on a fait, c'´etait un programme
de dump, pour pouvoir les lire. Mais pour pouvoir les lire, il suffit en
fait qu'ils soit dans un format de texte.

En fait, dans la VCL, TIniFile descend de TCustomIniFile, tout comme
TRegistryIniFile. De cette façon, on peut travailler en mode "ficier
.ini" et ensuite (éventuellement) passer en mode "registre système".


J'avoue que je n'ai jamais trop compris l'intérêt du registre système
sous Windows.

J'ai bien implémenté des classes de gestion de la configuration qui
lisent de tels fichiers. Je n'ai jamais choisi ce format quand c'est
le programme qui doit les écrire.


C'est un format Windows. Mais rien n'interdit de le réutiliser.


C'est devenu quasiment une standard pour les fichiers de configuration.
Je m'en suis servi dans les deux dernières applications, tous les deux
sous Unix. Pour la configuration ; je le vois mal pour la persistence.

Pour info : Une seule propriété : FileName


C'est un paramètre dans la ligne de commande, non ?


La propriété FileName est le nom complet du fichier INI, pas de
l'appli. TIniFile représente un fichier INI.


Oui. Tu invoques l'application :

appli fichier_de_config.ini

Avec éventuellement d'autres options, mais en voilà la principale.

Comme j'ai dit, je n'ai jamais vraiment vu l'intérêt du règistre sous
Windows.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



Avatar
Christophe Lephay
wrote:
J'avoue que je n'ai jamais trop compris l'intérêt du registre système
sous Windows.


La seule utilité qui me vient, c'est un certain nombre de facilités
d'administration à distance.

Ceci dit, le registre date de 95, et je suis pas sur qu'à ce moment là, il
était question d'administrer Windows à distance...

Chris