A voir également:
- Probleme d'ouverture de fichier
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Ouvrir fichier .bin - Guide
- Fichier host - Guide
10 réponses
Nxl
Messages postés
1038
Date d'inscription
mardi 2 février 2010
Statut
Membre
Dernière intervention
5 janvier 2017
133
4 juil. 2012 à 23:41
4 juil. 2012 à 23:41
Salut,
Mode "r" égal lecture seule mais si le fichier n'a pas été créé auparavant ta fonction ne va pas le faire. Tu peux utiliser le mode "a+" qui te permet de lire, d'écrire dans ton fichier et s'il n'existe pas ta fonction le créera.
Mode "r" égal lecture seule mais si le fichier n'a pas été créé auparavant ta fonction ne va pas le faire. Tu peux utiliser le mode "a+" qui te permet de lire, d'écrire dans ton fichier et s'il n'existe pas ta fonction le créera.
Nxl
Messages postés
1038
Date d'inscription
mardi 2 février 2010
Statut
Membre
Dernière intervention
5 janvier 2017
133
6 juil. 2012 à 12:45
6 juil. 2012 à 12:45
Euh... Non pas vraiment car là ton problème à l'air de venir du fait que le fichier text.txt n'existe pas donc soit tu le crées, soit tu laisse ta fonction le faire.
Nxl
Messages postés
1038
Date d'inscription
mardi 2 février 2010
Statut
Membre
Dernière intervention
5 janvier 2017
133
7 juil. 2012 à 01:06
7 juil. 2012 à 01:06
Enfin ton fichier ne s'appelle pas text.txt...
Nxl
Messages postés
1038
Date d'inscription
mardi 2 février 2010
Statut
Membre
Dernière intervention
5 janvier 2017
133
Modifié par antoine7104 le 6/07/2012 à 12:49
Modifié par antoine7104 le 6/07/2012 à 12:49
Enfin là, c'est très dur de voir d'où vient ton problème car on est loin d'avoir tout ton code et de savoir à quoi il sert : Tu nous parles de cette ligne :
fichier = fopen(fgets( file, sizeof(file), stdin), "r" );Mais elle ne figure jamais dans ton code...
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Utilisateur anonyme
Modifié par DJ Fire-Black le 7/07/2012 à 05:34
Modifié par DJ Fire-Black le 7/07/2012 à 05:34
Salut,
Alors ... pas mal de trucs incohérents dans ce code.
Premièrement,
Non seulement, ton %s ne sert à rien, c'est magnifique, mais en plus au lieu de mettre le fichier tu lui donnes stderr, bon ...
Voici la déclaration de fprintf :
Mais je pense que tu voulais utiliser printf, qui est totalement différent (En tout cas c'est mieux pour afficher une erreur)
Il y a aussi :
Si ton fichier ne contient qu'un seul chiffre, ok. Sinon, il faut faire une boucle.
Ensuite, je pense qu'il y a un buffer overflow. Tu alloues 2 à file et finalement avec sprintf tu vas lui en mettre beaucoup plus.
Donc je pense que ça bloque vers le 2ème No such file or directory.
Pourquoi ?
Pour l'histoire du buffer orverflow, tu vas te retrouver avec la variable file qui ne va contenir que 2 lettres et donc ce sera automatiquement le mauvais nom de fichier.
On arrive au moment où tu ouvres ce mauvais nom de fichier qui n'existera donc pas, ta variable fichier sera NULL, on entre dans le scope de la condition if(!fichier) et ton programme va afficher : No such file or directory : (null) !
Il y a aussi :
ça m'étonnerait que ça fonctionne. Si ça fonctionne, tant mieux, mais sinon je le verrais plutôt comme ça :
Musicalement,
DJ Fire-Bl@ck.
Alors ... pas mal de trucs incohérents dans ce code.
Premièrement,
fprintf(stderr,"No such file or directory : %s !\n");
Non seulement, ton %s ne sert à rien, c'est magnifique, mais en plus au lieu de mettre le fichier tu lui donnes stderr, bon ...
Voici la déclaration de fprintf :
int fprintf ( FILE * stream, const char * format, ... );
Mais je pense que tu voulais utiliser printf, qui est totalement différent (En tout cas c'est mieux pour afficher une erreur)
int printf ( const char * format, ... );
Il y a aussi :
n=fgetc(fichier); printf("%d \n", n); char file[2]; sprintf(file,"niveau%d.lvl", n ); fclose(fichier);
Si ton fichier ne contient qu'un seul chiffre, ok. Sinon, il faut faire une boucle.
Ensuite, je pense qu'il y a un buffer overflow. Tu alloues 2 à file et finalement avec sprintf tu vas lui en mettre beaucoup plus.
Donc je pense que ça bloque vers le 2ème No such file or directory.
n=fgetc(fichier); printf("%d \n", n); char file[2]; sprintf(file,"niveau%d.lvl", n ); fclose(fichier); char niveau[20]=file+ ".lvl"; fichier = fopen(file, "r" ); if(!fichier) { fprintf(stderr,"No such file or directory : %s !\n",fichier); exit(EXIT_FAILURE); }
Pourquoi ?
Pour l'histoire du buffer orverflow, tu vas te retrouver avec la variable file qui ne va contenir que 2 lettres et donc ce sera automatiquement le mauvais nom de fichier.
On arrive au moment où tu ouvres ce mauvais nom de fichier qui n'existera donc pas, ta variable fichier sera NULL, on entre dans le scope de la condition if(!fichier) et ton programme va afficher : No such file or directory : (null) !
Il y a aussi :
char niveau[20]=file+ ".lvl";
ça m'étonnerait que ça fonctionne. Si ça fonctionne, tant mieux, mais sinon je le verrais plutôt comme ça :
char niveau[20]; strcat(niveau, file); strcat(niveau, ".lvl");
Musicalement,
DJ Fire-Bl@ck.
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
8 juil. 2012 à 01:24
8 juil. 2012 à 01:24
Non seulement, ton %s ne sert à rien, c'est magnifique, mais en plus au lieu de mettre le fichier tu lui donnes stderr, bon ...
Effectivement, le %s ne sert à rien. Mais pour le stderr, je vois pas où est le problème. Il écrit simplement sur la sortie erreur qu'il y a eu un problème de lecture.
char niveau[20];
strcat(niveau, file);
strcat(niveau, ".lvl");
Ce n'est pas bon non plus. Il faut mettre : char niveau[20]={0};
Ou alors commencer par : strcpy(niveau, file);
Ou sinon un petit sprintf(niveau,"%s.lvl",file);
Effectivement, le %s ne sert à rien. Mais pour le stderr, je vois pas où est le problème. Il écrit simplement sur la sortie erreur qu'il y a eu un problème de lecture.
char niveau[20];
strcat(niveau, file);
strcat(niveau, ".lvl");
Ce n'est pas bon non plus. Il faut mettre : char niveau[20]={0};
Ou alors commencer par : strcpy(niveau, file);
Ou sinon un petit sprintf(niveau,"%s.lvl",file);
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
8 juil. 2012 à 01:28
8 juil. 2012 à 01:28
J'ai pas lu ton code, mais quand je vois : fichier = fopen(fgets( file, sizeof(file), stdin), "r" ); ça ne m'étonne pas que ça marche pas.
Ton file, ne contiendra qu'un caractère (cf. ta déclaration de file).
Je te conseille de plutôt tester le retour de fgets pour voir si la fonction a bien marché ou pas. Et si oui, à ce moment là tu fais un fopen.
Ton file, ne contiendra qu'un caractère (cf. ta déclaration de file).
Je te conseille de plutôt tester le retour de fgets pour voir si la fonction a bien marché ou pas. Et si oui, à ce moment là tu fais un fopen.
J'ai de mon coté fais des recherches et j'ai réussi à trouver ça
mais il m'affiche segment fault
et mon fichier sert à ouvrir un niveau selon le nombre qui est stoker dans test.txt
/* fichiers.c ---------- Par: remi Rôle : fonctions de lecture / écriture de fichiers de niveau. */ #include <stdlib.h> #include <stdio.h> #include <SDL/SDL.h> #include <SDL/SDL_image.h> #include "constantes.h" #include "fichiers.h" int chargerNiveau(int niveau[][NB_BLOCS_HAUTEUR]) { FILE *fichier = NULL; FILE *test = NULL; char ligneFichier[NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1] ; /* pas besoin de = "" */ int i = 0, j = 0, n = 0; char file[21]; //on ouvre le fichier test.txt et on le stocke dans test test=fopen("test.txt","r"); if(test != NULL) //**** toujours tester si l'ouverture est correcte { //on lis test.txt et on le stocke dans la variable n fscanf(test, "%d",&n); /* Definition de variable au milieu du code : interdit en C, mauvaise idee dans les autres langages */ //**** Mais autorisé en C99 sprintf(file,"niveau%d.lvl", n ); //**** format "%d" puisque n est un entier fclose(test); } else { printf("Impossible d'ouvrir le fichier test.txt"); return 0; } fichier = fopen (file, "r"); // s'est comme ça que tu dis de faire fgets(ligneFichier, NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1, fichier); for(i = 0; i < NB_BLOCS_LARGEUR; i++) { for(j = 0; j < NB_BLOCS_HAUTEUR; j++) { niveau[j][i] = ligneFichier[(i * NB_BLOCS_LARGEUR) + j] - '0'; } } fclose(fichier); return 1; } int sauvegarderNiveau(int niveau[][NB_BLOCS_HAUTEUR]) { FILE* fichier = NULL; int i = 0, j = 0; char file[21]; fichier = fopen(file,"r"); if(fichier == NULL) //**** toujours tester si l'ouverture est correcte { printf("Impossible d'ouvrir le fichier %s", file); return 0; } for(i = 0; i < NB_BLOCS_LARGEUR; i++) for(j = 0; j < NB_BLOCS_HAUTEUR; j++) fscanf(fichier, "%d",&niveau[j][i]); fclose(fichier); return 1; }
mais il m'affiche segment fault
et mon fichier sert à ouvrir un niveau selon le nombre qui est stoker dans test.txt
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
8 juil. 2012 à 11:36
8 juil. 2012 à 11:36
N'oublie pas de faire un if(fopen...) pour savoir si l'ouverture du fichier n'a pas échoué. Cela évite de réfléchir pendant une heure bêtement sur une erreur.
Ou : if(fichier=NULL)...
fgets(ligneFichier, NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1, fichier);
fgets ne lira pas tout le fichier. Il s'arrêtera à chaque ligne.
niveau[j][i]
Attention, tu as inversé j et i. Compte tenu des boucle for (i < NB_BLOCS_LARGEUR) et de la définition de niveau (int niveau[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR)
ce n'est pas étonnant pour le segfault.
Sinon le code est assez horrible lol.
Ou : if(fichier=NULL)...
fgets(ligneFichier, NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1, fichier);
fgets ne lira pas tout le fichier. Il s'arrêtera à chaque ligne.
niveau[j][i]
Attention, tu as inversé j et i. Compte tenu des boucle for (i < NB_BLOCS_LARGEUR) et de la définition de niveau (int niveau[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR)
ce n'est pas étonnant pour le segfault.
Sinon le code est assez horrible lol.
niveau[j][i] = ligneFichier[(i * NB_BLOCS_LARGEUR) + j] - '0';
S'est un tableau à deux dimensions ou on stocke les info pour afficher le jeu
porquoi ?
S'est un tableau à deux dimensions ou on stocke les info pour afficher le jeu
porquoi ?
après le = ligne fichier lit un fichier puis le stocke dans le tableau
Oui mais je voulais savoir en détails.
exemple pourquoi on a - '0' à la fin ?
niveau[j][i] = ligneFichier[(i * NB_BLOCS_LARGEUR) + j] - '0';
On va décomposer, dans l'ordre d'exécution.
1 -> i * NB_BLOCS_LARGEUR
2 -> + j
3 -> On récupère le char associé au résultat précédant dans le tableau ligneFichier
4 -> On "enlève" le caractère '0' au char récupéré. <- Je ne pense pas que ce soit possible. Si tu me disais ce que tu veux faire avec cette "soustraction" ce serait plus clair.
exemple pourquoi on a - '0' à la fin ?
niveau[j][i] = ligneFichier[(i * NB_BLOCS_LARGEUR) + j] - '0';
On va décomposer, dans l'ordre d'exécution.
1 -> i * NB_BLOCS_LARGEUR
2 -> + j
3 -> On récupère le char associé au résultat précédant dans le tableau ligneFichier
4 -> On "enlève" le caractère '0' au char récupéré. <- Je ne pense pas que ce soit possible. Si tu me disais ce que tu veux faire avec cette "soustraction" ce serait plus clair.
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
8 juil. 2012 à 11:24
8 juil. 2012 à 11:24
Le lignefichier est un tableau de char. Avec le -'0', cela convertit en int. Tout simplement.
Enfin c'est mon avis. C'est une astuce très courante.
Enfin c'est mon avis. C'est une astuce très courante.
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
8 juil. 2012 à 11:50
8 juil. 2012 à 11:50
Dans ce cas, pourquoi ne pas utiliser atoi ?
atoi c'est sur une chaîne de caractères. Pas sur un char.
Et puis atoi c'est deprécié. Il faut utiliser plutôt strtol.
En tout cas, ce n'est pas le -'0' l'erreur. Tu fais juste une soustraction de codes ascii pour récupérer la valeur du chiffre.
atoi c'est sur une chaîne de caractères. Pas sur un char.
Et puis atoi c'est deprécié. Il faut utiliser plutôt strtol.
En tout cas, ce n'est pas le -'0' l'erreur. Tu fais juste une soustraction de codes ascii pour récupérer la valeur du chiffre.
en faite j'ai fais ça un soir mais je ne me rappelle pas pourquoi j'ai mis ça ni même si je l'ai pris sur un autre forum
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
8 juil. 2012 à 11:52
8 juil. 2012 à 11:52
Ce qui serait pratique, ça serait que tu tiennes compte de mes remarques. T'as inversé le i et le j... Pas étonnant que ça segfault.