Langage C : lire un tableau depuis un fichier
Résolu/Fermé
Metabolic
-
2 déc. 2010 à 14:54
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 7 déc. 2010 à 00:11
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 7 déc. 2010 à 00:11
A voir également:
- Lire un tableau en c
- Langage ascii - Guide
- Langage binaire - Guide
- Pascal langage - Télécharger - Édition & Programmation
- Langage pascal - Télécharger - Édition & Programmation
- Delphi (langage) - Télécharger - Langages
5 réponses
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
2 déc. 2010 à 15:29
2 déc. 2010 à 15:29
la lecture est en effet un peu plus compliqué compliqué. il faut utiliser fscanf pour lire le fichier.
ton freopen est plutôt malin pour éviter de faire une deuxième fonction d'écriture. Je me pose juste une question, est-ce que close(stdout) restaure le flux sur la sortie standard ?
Pour ta lecture de grille :
ton freopen est plutôt malin pour éviter de faire une deuxième fonction d'écriture. Je me pose juste une question, est-ce que close(stdout) restaure le flux sur la sortie standard ?
Pour ta lecture de grille :
FILE* fi=fopen("save.txt","r"); for(j=0;j<2;++j) for(n=0;n<N;++n) { for(m=0;m<N;++m) scanf("%c",&grille[n][m]); scanf("\n"); }
Merci pour le code mais tu dis qu'il faut utiliser fscanf et t'as juste utilisé des scanf.
(un oubli sans importance vu qu'ils sont bien placés :) )
Et pr répondre à ta question je pense que oui après le fclose, stdout redevient standard.
(un oubli sans importance vu qu'ils sont bien placés :) )
Et pr répondre à ta question je pense que oui après le fclose, stdout redevient standard.
Hum sa serait quoi alors si je devais changer aussi mon code pour save?
Un truc genre :
FILE* fi=fopen("save.txt","r");
blabla avec fprintf
fclose(fi)
??
Un truc genre :
FILE* fi=fopen("save.txt","r");
blabla avec fprintf
fclose(fi)
??
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
3 déc. 2010 à 08:22
3 déc. 2010 à 08:22
une solution si tu veux faire qu'une routine, c'est de modifier ta fonction aff_grille et mettre :
aff_grille(Grille A,Grille B,FILE * s=stdout);
vérifier qu'en C on peut bien mettre un argument par défaut.
Ensuite, tu modifie tout les printf de ta fonction par des fprintf(s,...)
Dans le reste du code, la seule modification à faire sera alors d'appeler aff_grille avec en argument l'identifiant du fichier.
aff_grille(Grille A,Grille B,FILE * s=stdout);
vérifier qu'en C on peut bien mettre un argument par défaut.
Ensuite, tu modifie tout les printf de ta fonction par des fprintf(s,...)
Dans le reste du code, la seule modification à faire sera alors d'appeler aff_grille avec en argument l'identifiant du fichier.
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 842
3 déc. 2010 à 09:06
3 déc. 2010 à 09:06
Nop, pas d'argument par défaut en C..
Pour écrire dans un fichier, tu peux simplement utliser un fprintf.
Sinon, tu as deux joueurs dans une bataille navale, il faut donc 2 grilles. Chacune des grilles contiendra 4 valeurs (0 si aucun bateau et pas de missile lancée sur cette zone, 1 si présence bateau et pas de missile lancée, ...). Tu peux faire un enum pour plus de clarté.
Ensuite, pour ta grille, il te faut une autre dimension pour stocker les deux grilles. Par exemple : int grille[2][N][N]; Sinon tu peux utiliser une structure aussi.
Ensuite plutôt que t'embêter avec fprintf/fscanf, un simple fread/fwrite te fera la lecture/écriture en une passe.
Cordialement,
Pour écrire dans un fichier, tu peux simplement utliser un fprintf.
Sinon, tu as deux joueurs dans une bataille navale, il faut donc 2 grilles. Chacune des grilles contiendra 4 valeurs (0 si aucun bateau et pas de missile lancée sur cette zone, 1 si présence bateau et pas de missile lancée, ...). Tu peux faire un enum pour plus de clarté.
Ensuite, pour ta grille, il te faut une autre dimension pour stocker les deux grilles. Par exemple : int grille[2][N][N]; Sinon tu peux utiliser une structure aussi.
Ensuite plutôt que t'embêter avec fprintf/fscanf, un simple fread/fwrite te fera la lecture/écriture en une passe.
Cordialement,
t'inquiète pas pr les grilles, j'ai déja fait une grande partie du programme du jeu. Simplement, j'aimerai savoir si cette version de load, codée à partir de vos commentaires, est correcte. Je vous mets aussi les structs de départ pr pouvoir comprendre.
#define N 10
typedef char Grille[N][N];
typedef struct{
char typeB;
int Nbcases;
int absOrig;
int ordOrig;
int Orientation[2];
}bateau;
typedef struct{
int Nbship;
bateau tabShip[N];
}listeBateau;
void load(Grille A,Grille B,Grille A2,Grille B2,listeBateau lp,listeBateau lo){
FILE* fi=fopen("save.txt","r");
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&A[n][m]);
}
fscanf("\n");
}
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&B[n][m]);
}
fscanf("\n");
}
fscanf("\n");
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&A2[n][m]);
}
fscanf("\n");
}
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&B2[n][m]);
}
fscanf("\n");
}
fscanf("%d",&lp.Nbship);
for(i=0;i<N;i++){
fscanf(" %c,%d,%d,%d,%d,%d",&((lp.tabShip)[i].typeB),&((lp.tabShip)[i].Nbcases),&((lp.tabShip)[i].absOrig),&((lp.tabShip)[i].ordOrig),&((lp.tabShip)[i].Orientation[0]),&((lp.tabShip)[i].Orientation[1]));
}
fscanf("\n");
fscanf("%d",&lo.Nbship);
for(i=0;i<N;i++){
fscanf(" %c,%d,%d,%d,%d,%d",&((lo.tabShip)[i].typeB),&((lo.tabShip)[i].Nbcases),&((lo.tabShip)[i].absOrig),&((lo.tabShip)[i].ordOrig),&((lo.tabShip)[i].Orientation[0]),&((lo.tabShip)[i].Orientation[1]));
}
fclose(fi);
}
Je sais que niveau lisibilité c'est pas la fête mais bon si ça marche sa me suffira pour le moment. Quant à save je prévois de faire la même chose en remplaçant les fscanf par des fprintf.
#define N 10
typedef char Grille[N][N];
typedef struct{
char typeB;
int Nbcases;
int absOrig;
int ordOrig;
int Orientation[2];
}bateau;
typedef struct{
int Nbship;
bateau tabShip[N];
}listeBateau;
void load(Grille A,Grille B,Grille A2,Grille B2,listeBateau lp,listeBateau lo){
FILE* fi=fopen("save.txt","r");
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&A[n][m]);
}
fscanf("\n");
}
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&B[n][m]);
}
fscanf("\n");
}
fscanf("\n");
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&A2[n][m]);
}
fscanf("\n");
}
for(n=0;n<N;++n){
for(m=0;m<N;++m){
fscanf("%c",&B2[n][m]);
}
fscanf("\n");
}
fscanf("%d",&lp.Nbship);
for(i=0;i<N;i++){
fscanf(" %c,%d,%d,%d,%d,%d",&((lp.tabShip)[i].typeB),&((lp.tabShip)[i].Nbcases),&((lp.tabShip)[i].absOrig),&((lp.tabShip)[i].ordOrig),&((lp.tabShip)[i].Orientation[0]),&((lp.tabShip)[i].Orientation[1]));
}
fscanf("\n");
fscanf("%d",&lo.Nbship);
for(i=0;i<N;i++){
fscanf(" %c,%d,%d,%d,%d,%d",&((lo.tabShip)[i].typeB),&((lo.tabShip)[i].Nbcases),&((lo.tabShip)[i].absOrig),&((lo.tabShip)[i].ordOrig),&((lo.tabShip)[i].Orientation[0]),&((lo.tabShip)[i].Orientation[1]));
}
fclose(fi);
}
Je sais que niveau lisibilité c'est pas la fête mais bon si ça marche sa me suffira pour le moment. Quant à save je prévois de faire la même chose en remplaçant les fscanf par des fprintf.
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 842
3 déc. 2010 à 14:00
3 déc. 2010 à 14:00
Effectivement, c'est pas clair du tout.
Quand tu postes du code, utilise les balises "code" (à droite du bouton souligné), ça sera beaucoup plus lisible pour nous.
Sinon, tu as mis des fscanf("\n"), ça ne correspond à rien.
Ensuite, ton code est bien trop compliqué...
En une ligne, tu peux faire ta fonction load et open avec fread et fwrite. Pas besoin de faire de boucle etc.
Cdlt,
Quand tu postes du code, utilise les balises "code" (à droite du bouton souligné), ça sera beaucoup plus lisible pour nous.
Sinon, tu as mis des fscanf("\n"), ça ne correspond à rien.
Ensuite, ton code est bien trop compliqué...
En une ligne, tu peux faire ta fonction load et open avec fread et fwrite. Pas besoin de faire de boucle etc.
Cdlt,
ya pas besoin de lire les retours a la ligne? ah ok....mais par contre je vois pas comment en une ligne je peux faire ma fonction load ou save vu que fread est assez compliqué à utiliser et j'ai 4 grilles et 2 structures à charger/sauvegarder.
On a pas encore vraiment étudié les pbs de fichier et mémoire en c donc je comprends pas tout...
On a pas encore vraiment étudié les pbs de fichier et mémoire en c donc je comprends pas tout...
fanowine
Messages postés
20
Date d'inscription
vendredi 9 avril 2010
Statut
Membre
Dernière intervention
24 juillet 2019
1
6 déc. 2010 à 23:44
6 déc. 2010 à 23:44
le probleme avec fscanf est que cette fonction lit mot apres mot
alors que tu conviens avec moi que cela est un peut rude parcontre avec le cas de caractere par caractère tu gere ton contenue comme tu veux
alors que tu conviens avec moi que cela est un peut rude parcontre avec le cas de caractere par caractère tu gere ton contenue comme tu veux
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 842
7 déc. 2010 à 00:11
7 déc. 2010 à 00:11
le probleme avec fscanf est que cette fonction lit mot apres mot
Sauf que fscanf n'est pas une fonction qui lit mot à mot. Cela dépend du format passé en argument. Dans nos exemples, on utilisait fscanf(fp,"%c",...) et dans ce cas ça lit caractère par caractère comme ton fgetc... Un petit lien pour voir ce que fait scanf : http://www.linux-france.org/article/man-fr/man3/scanf-3.html
alors que tu conviens avec moi que cela est un peut rude parcontre avec le cas de caractere par caractère tu gere ton contenue comme tu veux
Oui je conviens. Par contre, tu conviendras avec moi qu'un simple fread est encore moins rude que la gestion du caractère par caractère...
Sauf que fscanf n'est pas une fonction qui lit mot à mot. Cela dépend du format passé en argument. Dans nos exemples, on utilisait fscanf(fp,"%c",...) et dans ce cas ça lit caractère par caractère comme ton fgetc... Un petit lien pour voir ce que fait scanf : http://www.linux-france.org/article/man-fr/man3/scanf-3.html
alors que tu conviens avec moi que cela est un peut rude parcontre avec le cas de caractere par caractère tu gere ton contenue comme tu veux
Oui je conviens. Par contre, tu conviendras avec moi qu'un simple fread est encore moins rude que la gestion du caractère par caractère...
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
fanowine
Messages postés
20
Date d'inscription
vendredi 9 avril 2010
Statut
Membre
Dernière intervention
24 juillet 2019
1
5 déc. 2010 à 11:34
5 déc. 2010 à 11:34
je suggère que tu utilise la fonction 'fget(FILE *fi)'.
cette fonction retourne un caractère.
cette fonction te permet de parcourir bien ton fichier et de copier dans ton tableau les caractères dont tu a besoin
exemple tu connais le code asci de tout les chiffres si c'est sa que tu as besoin
alors tu pourras copier tous les chiffres de la maniere qu'il ont été sauvegardé
cette fonction retourne un caractère.
cette fonction te permet de parcourir bien ton fichier et de copier dans ton tableau les caractères dont tu a besoin
exemple tu connais le code asci de tout les chiffres si c'est sa que tu as besoin
alors tu pourras copier tous les chiffres de la maniere qu'il ont été sauvegardé
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 842
5 déc. 2010 à 12:18
5 déc. 2010 à 12:18
Ce n'est pas la fonction fget mais fgetc.
Et c'est un peu le même problème que la fonction scanf("%c",...), cela rend le code compliqué car il faut user de boucle for et traduire la "complexité" des structures.
Un simple fread suffit...
Et c'est un peu le même problème que la fonction scanf("%c",...), cela rend le code compliqué car il faut user de boucle for et traduire la "complexité" des structures.
Un simple fread suffit...
2 déc. 2010 à 23:09
scanf("%\n") ?
Tu souhaites faire quoi ?
Ensuite, j'imagine que tu voulais mettre fscanf au lieu du scanf ?
Et pourquoi une boucle j<2 ?
Sinon, attention au redirection...
Il n'y a pas de solution portable pour restaurer le flux sur la sortie standard.
Pour réussir, il faut jouer avec dup / dup2 et sauvegarder le descripteur par dup(fileno(stdout));
Bref rien de très joli. Il vaut mieux éviter ce genre de redirection.
Cdlt,
3 déc. 2010 à 08:19
Je voulais juste donner l'algorithme général. La boucle sur "j", c'est car tu as deux grilles. Mais après relecture, il y en a 4 : 2 pour chaque joueur.
Merci de ta réponse sur stdout, ça me semblait trop simple aussi.