Problème avec fgets (langage C)
aurel94
Messages postés
82
Statut
Membre
-
[Dal] Messages postés 6373 Statut Contributeur -
[Dal] Messages postés 6373 Statut Contributeur -
Bonjour, je dois écrire un programme en C qui exploite des images pgm . L'image pgm s'écrit sous forme ascii ou binaire de la même façon
P2(binaire) ou P5(Ascii)
# commentaire
24 7 (largeur et hauteur)
15 (valeur de gris maximum)
....
....
.... (valeur des pixels en ascii ou binaire)
Je dois écrire un programme qui charge mon image , pour cela elle doit d'abord déterminer si l'image est en Ascii ou en binaire , et pour cela on doit lire la 1ere ligne . Voici le début de ma fonction
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "image.h"
#define TMP_STR_SIZE 256
image_t *charger_image_pgm(char *nom_fichier)
{
FILE *pF; // pointeur sur fichier
short ascii;
char ligne [1000];
int val_gris , i , j ;
image_t *pI ; //pointeur vers la nouvelle image
pI=malloc(sizeof(image_t)) ;
// Ouverture du fichier
pF=fopen(nom_fichier, "rt");
if (pF==NULL){
printf("fichier %s introuvable \n", nom_fichier);
return NULL;
}
//Lecture de la première ligne (type)
do {fgets (ligne, 999, pF);
} while (fgets(ligne,999,pF)!=NULL && ligne [0]=='#');
Le do while sert à zapper les lignes de commentaire et à lire seulement les infos interessante . Seulement voila il s'avère que ma fonction lit la DEUXIEME ligne avec hauteur/largeur et pas la première . J'ignore les raison de ce problème , merci de m'aider :D
P2(binaire) ou P5(Ascii)
# commentaire
24 7 (largeur et hauteur)
15 (valeur de gris maximum)
....
....
.... (valeur des pixels en ascii ou binaire)
Je dois écrire un programme qui charge mon image , pour cela elle doit d'abord déterminer si l'image est en Ascii ou en binaire , et pour cela on doit lire la 1ere ligne . Voici le début de ma fonction
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "image.h"
#define TMP_STR_SIZE 256
image_t *charger_image_pgm(char *nom_fichier)
{
FILE *pF; // pointeur sur fichier
short ascii;
char ligne [1000];
int val_gris , i , j ;
image_t *pI ; //pointeur vers la nouvelle image
pI=malloc(sizeof(image_t)) ;
// Ouverture du fichier
pF=fopen(nom_fichier, "rt");
if (pF==NULL){
printf("fichier %s introuvable \n", nom_fichier);
return NULL;
}
//Lecture de la première ligne (type)
do {fgets (ligne, 999, pF);
} while (fgets(ligne,999,pF)!=NULL && ligne [0]=='#');
Le do while sert à zapper les lignes de commentaire et à lire seulement les infos interessante . Seulement voila il s'avère que ma fonction lit la DEUXIEME ligne avec hauteur/largeur et pas la première . J'ignore les raison de ce problème , merci de m'aider :D
A voir également:
- Problème avec fgets (langage C)
- Langage ascii - Guide
- Langage binaire - Guide
- Langage visual basic - Télécharger - Langages
- Pascal langage - Télécharger - Édition & Programmation
- Langage basic gratuit - Télécharger - Édition & Programmation
4 réponses
J'ai oublier de dire que image_t était une structure créer qui stocke toute le informations nécessaire de l'image (hauteur , largeur , chemin , et valeur des pixels)
Salut aurel94,
En faisant :
Tu demandes la lecture d'une ligne deux fois : une fois à l'intérieur de la boucle do / while et une 2ème fois dans le test while.
Dans ton test while, tu devrais tester le contenu de "ligne".
Dal
En faisant :
do {fgets (ligne, 999, pF);
} while (fgets(ligne,999,pF)!=NULL && ligne [0]=='#');
Tu demandes la lecture d'une ligne deux fois : une fois à l'intérieur de la boucle do / while et une 2ème fois dans le test while.
Dans ton test while, tu devrais tester le contenu de "ligne".
Dal
Ah oui merci pour cette aide , c'est vrai que sa parait évident , du coup le contenu du fgets je dois le stocker dans un pointeur de caractère pour tester si il a la valeur NULL j'imagine ? :)
Le "stockage" est déjà fait dans "ligne" quand tu fais
Il faut distinguer ce stockage du retour de la fonction, que tu peux effectivement stocker dans un pointeur additionnel, pour pouvoir le tester, ou tu peux aussi certainement tout regrouper dans une boucle while.
Dal
Edit : retrait de code erroné.
fgets(ligne, 999, pF);, qui est un
char ligne[1000];, ce qui veut dire que "ligne" est un pointeur vers une zone mémoire allouée pouvant contenir 1000 char. C'est "ligne" que tu vas tester dans ton test while pour
ligne[0] == '#'.
Il faut distinguer ce stockage du retour de la fonction, que tu peux effectivement stocker dans un pointeur additionnel, pour pouvoir le tester, ou tu peux aussi certainement tout regrouper dans une boucle while.
Dal
Edit : retrait de code erroné.
Comme cela :
ou comme cela :
Dal
P.S. : j'ai ajouté des parenthèses au while, même si elles ne sont pas indispensables, car je n'aime pas me poser des questions existentielles
char * p;
do
{
p = fgets(ligne, 999, pF);
} while ((p != NULL) && (ligne[0] == '#'));
ou comme cela :
while ((fgets(ligne, 999, pF) != NULL) && (ligne[0] == '#'))
/* ignorer les lignes commençant par '#' */ ;
Dal
P.S. : j'ai ajouté des parenthèses au while, même si elles ne sont pas indispensables, car je n'aime pas me poser des questions existentielles
Merci beaucoup pour ces indications très intéressante . Pendant qu'on parle de valeur de retour connais tu les valeurs de retour de sscanf . Car j'aimerai tester si l'initialisation de mes variables avec des valeurs provenant d'une chaîne de caractère c'est bien passer mais je ne connait pas la valeur de retour de sscanf
Sur ce site, tu trouves une bonne source d'informations :
http://www.cplusplus.com/reference/cstdio/sscanf/
le prototype est
Le
- en cas de succès : le nombre d'éléments lus attendus remplis avec succès (disons N)
- sinon, de 0 à N-1 : nombre d'éléments lus inférieurs au nombre d'éléments attendus en cas d'erreur de correspondance
- ou EOF si rien n'a pu être lu en raison d'une interruption du flux lu
Dal
http://www.cplusplus.com/reference/cstdio/sscanf/
le prototype est
int sscanf ( const char * s, const char * format, ...);.
Le
intretourné est :
- en cas de succès : le nombre d'éléments lus attendus remplis avec succès (disons N)
- sinon, de 0 à N-1 : nombre d'éléments lus inférieurs au nombre d'éléments attendus en cas d'erreur de correspondance
- ou EOF si rien n'a pu être lu en raison d'une interruption du flux lu
Dal