Comment on fait si c´est une application console et qu´on veut mesurer le temps depuis le démarage d´une application ?
ben le mieux :
unsigend long temps_debut;
int main()
{
temps_debut=timeGetTime(); / * sauve le temps */
. ...
/ * programme */
. ...
tempsquetuveux = timeGetTime() - temps_debut;
tout simplement ![]()
timeGetTime indique le temps qui s´est déroulé de puis l´ouverture du programme ?
Et en quelle unité le temps est mesuré ?
" cette fonction te renvoie, sous forme de ulong, le compteur de temps depuis que t´as allumé ton PC, en milliemes de secondes, à + ou - 5 millisecondes dans le pire des cas : c´est assez fiable."
cf 4 messages plus haut ![]()
Ok merci
J´aurais une question particulièrement théorique ( en espérant que personne ne l´ai posé... mais ça m´étonnerait).
Je cherche à me renseigner sur la compilation de données en binaire. Pas que je m´oppose au ASCII mais ce n´est, pour un jeu du moins, rien d´efficace.
J´ai bien trouvé un guide pour la création d´un compilateur écrit par Télémachos de Peroxyde...
http://www.peroxide.dk/tuts_scr.shtml
Mais c´est vraiment plusieurs coches au-dessus de ce que je recherche, j´aimerais connaitre, comme je l´ai déjà dis, la théorie de base ( Est-ce qu´il y des maths à faire ? Ou est-ce que C++ vient avec des fonctions pré-conçues pour la tâche ? Quels avantages le binaire a sur le ASCII ? Peut-être un exemple d´application simple dans C++ ? ).
Un site web de référence serait bienvenu
j´ai un peu de mal à trouver quels mots clefs je pourrais bien taper dans google...
Je ne suis pas sur d´avoir tout saisi sur ce que tu demandes : je vais quand meme essayer de té répondre sur ce que je pense avoir compris :
Tout d´abord, un compilateur convertit, a ma connaissance, TOUJOURS de l´ASCII vers le binaire :
en effet, les fichiers EXE sont une suite de codes machines ( forme simple FONCTION,ADRESSE ( *)). Les compilateurs sont écrits pour simplifier la tache au programmeur, et un programmeur tape en ASCII.
Peut etre ne parles tu pas de compilateur mais de PARSER ( *) ( programme dont le but est de décoder des fichiers quelconques)
Mais bon, je repars sur le compilateur :
un compilateur est avant tout un " Analyseur syntaxique"
il sait reconnaitre des formes.
Par exemple, une forme en C :
T F(X)
{
C
}
le compilateur sait reconnaitre cela. On lui a appris que " T" est le type, il regarde si T est un type connu : si ce n´est pas le cas, il renvoie " type inconnnu", il regarde ensuite F, il l´ajoute a la liste des fonctions connues. ( dès qu´il reverra cela, il regardera s´il fait partie de sa liste, sinon : " fonction inconnue".
Ensuite, X est soit de la forme I, soit I,X. Avec ces 2 formes, tu détectes un nombre variable d´arguments ( *)
Ensuite, C est le corps.
Les analyses sont tres récursives.
Chaque fonction, si tu desend bas, fini par etre codée en code machine. Ainsi, il reconstruit le code machine global par analyse.
Apres, si tu veux te faire toi meme un petit compilateur, des langages sont développés pour faire a ta place des analyses syntaxiques : recherche LEX et YACC.
Les regles d´analyse sont appelées " grammaire", il existe des grammaires LR(0) et LL(1) par exemple. Je ne me souviens plus exactement les différences de ces grammaires...
Précise ce que tu veux savoir + en détail !
Heum heum, et bien je vais tenter de clarifier ma question en espérant que ce que je demande ne repose pas sur des principes faux que j´ai imaginé en tentant de comprendre.
Je ne veux pas faire un compilateur à proprement parler ( je n´essais pas de faire un langage), je cherche à storer de l´information.
Prenons, par exemple, un jeu dans lequel il est possible de sauvegarder. Je vois rarement un fichier de sauvegarde dans lequel toutes les informations sont disponibles en texte. Il s´agit toujours de caractères illisibles.
J´ai cru comprendre qu´il s´agissait de données sauvegardés en binaire ( il ne s´agit sûrement pas d´encryption, les fichiers de sauvegarde ne serait pas si souvent facile à éditer en hexa si c´était le cas). Je cherche la théorie à ce sujet.
D´accord, il s´agit de codage
et donc on parle de PARSER : les parsers sont des programmes ( ou des sous programmes) dont le but est de lire un fichier spécifique.
Je n´ai pas de sites sous la main : mais pour en parler rapidement :
Prenons l´exemple d´un jeu : dedans tu as X players, dont les ennemis.
Chaque player a : sa vie ; sa position x,y ; son type ( ordi ou humain)
tu vas définir un codage pour ton fichier a sauver : tu vas ouvrir le fichier en écriture binaire, et tu vas envoyer :
X sous 4 octets
puis, pour chaque joueur :
vie : 4 octets
x : 2 octets
y : 2 octets
type : 1 octet
le tout a la suite.
Ainsi sera fait ton fichier de sauvegarde, il sera binaire : illisible au bloc note.
Pour pouvoir le relire, il te faudra connaitre le SCHEMA de lecture ( le schema, c´est ce que j´ai donné au dessus, qui dit comment le tout est rangé)
de la, tu pourras faire un PARSER de lecture :
tu liras d´abord les 4 premiers octets que tu rentreras dans l´int X, ensuite, tu sauras qu´il faudra lire X enregistrements
et pour chacun tu sauras que les 4 premiers sont la vie, les 2 suivants x, les 2 suivants y, le suivant le type. et les données suivantes sont le joueur d´apres, jusqu´a ce que tu aies lu X joueurs.
et tu récuperes toutes tes données.
pour lire et écrire dans des fichiers binaire, si tu utilises stdio, c´est fread et fwrite.
et je te dirais que tu peux lire n´importe quel type de fichiers si tu connais le schema.
bon, c´était un résumé rapide, j´espere que tu vois a peu pres comment ça marche. Pour les sites je n´en connais pas, mais si tu as des questions spécifiques, n´hésite pas, j´ai déja programmé des parsers, et déja fait des petits fichiers de sauvegarde en binaire.
Ça couvre la théorie de base, merci bien
. Voyons un peu ce que msdn dit de fread et fwrite...
fread et fwrite pour faire simple :
ça envoie des octets dans un fichier, a la suite ![]()
tu dis combien tu veux en envoyer ou en lire, tu dis a partir de quelle adresse, et pan, ça les envoie a la suite dans le fichier pour fwrite, et ça les recupere a l´endroit de lecture de fichier pour fread ![]()
Donc si je comprends bien, j´ai le plan d´un fichier du genre
sauvegarde.sav
vie : 4 octets
x : 2 octets
y : 2 octets
Si je veux récupérer les données, j´ouvre un pointer de type file.
FILE *sauvegarde;
J´ouvre le fichier en mode rb ( read et binary)
sauvegarde = fopen("sauvegarde.sav" , " rb");
si je veux juste les vies, j´indique simplement
char bufferVie[5];
fread(bufferVie , 4 , 1 , sauvegarde);
bufferVie[4] = ´\0´;
int Vie = atoi(bufferVie);
pour récupérer toutes les informations, je répète la procédure en changeant le paramètre size de fread ( comme le pointeur ce déplace gentillement dans le fichier).
et si je voulais récupérer, par exemple, uniquement x avec un pointeur tout frais.
FILE pointeurfrais;
pointeurfrais = fopen("sauvegarde.sav" , " rb");
fseek(pointeurfrais , 4 , 0); / / On déplace le pointeur au-delà des 4 octets de vie pour atteindre x
char bufferX[3];
fread(bufferX , 4 , 1 , sauvegarde);
bufferX = [2] = ´\0´;
int x;
x = atoi(bufferX);
C´est bien ça ? Je n´arrive pas à me souvenir s´il faut manuellement terminé les char ( le = ´\0´) avec un fread... ?
Oups, un signe de = c´est glissé là où il ne devrait pas y en avoir à la ligne
bufferX = [2] = ´\0´;
je voulais dire
bufferX[2] = ´\0´;
Dhaaarr et la ligne
FILE pointeurfrais;
devrait être
FILE *pointeurfrais;
dslé, j´ai écrit tout ça directement dans la text box du forum
.
voila, tu as comrpis le truc ![]()
pour les char : oui il faudrait mettre le \0 manuellement, mais tu te compliques la vie :
tu n´es pas obligé de passer par un tableau de char :
FILE* F;
. ..
int vie;
fwrite(&,sizeof(int),1,F);
ça marche direct
tu écrit direct dans ton int
et pour le relire
int vie;
fread(&,sizeof(int),1,F);
sachant que sizeof(int) = 4
mais c´est + propre de mettre sizeof
essaie de te faire un exemple ! tu fais un petit prog qui sauve des données ( au pif)
et tu fais un autre programme qui les lit.
et entre temps, tu essaie de lire le fichier de sauvegarder au bloc note, tu verras que C binaire
PS : ne dis pas plan, mais bien SCHEMA
c´est le terme connu !
je te conseille d´utiliser les sizeof pour bien ranger toute la variable
car un int étant 4 octets, si tu ranges que 2 octets dedans, les 2 autres peuvent etre n´importe quoi, et tu es foutu !
pour rester cohérant, fais bien :
int vie;
fwrite(&,sizeof(int),1,F);
short vie;
fwrite(&,sizeof(short),1,F);
char vie;
fwrite(&,sizeof(char),1,F);
TRUC vie;
fwrite(&,sizeof(TRUC),1,F);
et la tu n´auras pas d´ennuis ![]()
tu peux ranger tout un tableau aussi d´un coup :
int donnee[25];
fwrite(&,sizeof(int),25,F);
enfin bref, tu vois bien ![]()
C´est pas dangereux de lire directement dans un int? Si jamais le fichier est modifié / corrompu, le programme risque de planter magistralement alors que atoi règle le problème en mettant 0 dans le int en cas de problème.
Quoiqu´il en soit, merci beaucoup, ça répond très bien à mes interrogations, je vais aller essayer de faire un p´tit prog, comme suggéré
.
ben essaie de modifie une sauvegarde d´un jeu vidéo du marché en mettant des octets d´importe ou. Y´en a pas mal qui vont planter
moi je pense que c´est pas la peine de se casser la tete avec atoi, mais bon ! apres, ça se discute bien sur !
le truc qui peut etre dangereux, c´est si tu écris un fichier avec un processeur de MAC, et que tu le lis avec un pross PC ( big endian/little endian) mais je pense que tu n´as pas a t´en occuper
Bon, sur ce je dois y aller, je te souhaite une bonne soirée ![]()