Je dois écrire une fonction chargée d'extraire le 2ème champs de chacune
des lignes d'un fichier texte (exemple de lignes reproduit en bas de post).
Ce champ est composé de 7 caractères (exemple : 945BB04) et je ne dois
stocker que les champs commençants par '9'. Bien sûr, avant de stocker
un champs, la fonction vérifie s'il n'a pas déjà été préalablement
stocké (champs identiques).
Mais je rencontre un problème en fonction de la fin du fichier qui peut
être n'importe quoi, c'est à dire que la dernière ligne du fichier peut
se terminer par n'importe quoi, exemples :
- par une série d'espaces SANS '\n' : le pgm fonctionne bien.
- par un '\n' (avec ou sans espace avant, peu importe) : le pgm
fonctionne bien.
- mais si la dernière ligne est composée uniquement d'espaces suivi OU
NON par un '\n' ou bien s'il y a plusieurs lignes d'espaces avec ou sans
'\n' à la fin : le pgm boucle indéfiniment.
Et c'est ce dernier cas qui pose un problème : le programme boucle
indéfiniment sur cette fin de fichier (lignes de code commentées en
majuscules)
Comment procéder pour que le programme fonctionne quelque soit la
dernière ligne?
Merci d'avance.
Michel
int caractereLu;
char **pTabIdPub = NULL;
char identifiantLu[TAILLE_BUFFER];
Booleen idNonStocke; /*typedef enum logique {FAUX, VRAI} Booleen; dans
un .h*/
int i;
int j = 0;
int k;
/* tant que l'on n'a pas atteint la fin de fichier */
while((caractereLu = fgetc(pFichierRF)) != EOF) {
i = 0;
idNonStocke = FAUX;
/* tant que l'on n'a pas trouvé un 9 */
while(caractereLu != '9')
caractereLu = fgetc(pFichierRF);
/* on mémorise le 9 */
identifiantLu[i++] = caractereLu;
/* on lit et mémorise jusqu'à l'espace suivant exclu, sans
toutefois dépasser 6 caractères */
while((caractereLu = fgetc(pFichierRF)) != ' ' && i < 7)
identifiantLu[i++] = caractereLu;
/* on ajoute le caractère de fin de chaine */
identifiantLu[i] = '\0';
/* on vérifie si le contenu de identifiantLu est déjà stocké */
if(j >= 1) {
for(k = 0; k < j; k++) {
if(strcmp(pTabIdPub[k], identifiantLu))
idNonStocke = VRAI;
}
}
if(j <= 1 || idNonStocke == VRAI) {
/* on réserve de la mémoire pour stocker un pointeur vers la chaine
id_de_la_pub */
if((pTabIdPub = realloc(pTabIdPub, sizeof(char*) *(j+1))) ==
NULL) {
printf("Module \"%s\"\nLigne %d : echec d'allocation memoire
par \"realloc\".\n"
"Le programme ne peut continuer.\n\n",
NOM_MODULE, __LINE__);
printf("Pressez <enter> pour quitter le programme.");
fflush(stdout);
getchar();
exit(EXIT_FAILURE);
}
/* on stocke l'identifiant de la pub */
if((pTabIdPub[j] = strdup(identifiantLu)) == NULL) {
printf("Module \"%s\"\nLigne %d : echec d'allocation memoire
par \"strdup\".\n"
"Le programme ne peut continuer.\n\n", NOM_MODULE,
__LINE__);
printf("Pressez <enter> pour quitter le programme.");
fflush(stdout);
getchar();
exit(EXIT_FAILURE);
}
}
j++;
/* on lit jusqu'à la ligne suivante : ICI LE PGM BOUCLE EN
FONCTION DU TYPE DE LA DERNIERE LIGNE */
while((caractereLu = fgetc(pFichierRF)) != '\n' /*|| caractereLu
!= EOF*/) {
if(caractereLu == EOF)
break;
}
}
/* affichage des lignes stockées */
for(k = 0; k < j; k++) {
printf("Ligne n. %05d : %s\n", k + 1, pTabIdPub[k]);
}
}
Mais je rencontre un problème en fonction de la fin du fichier qui peut être n'importe quoi, c'est à dire que la dernière ligne du fichier peut se terminer par n'importe quoi, exemples : - par une série d'espaces SANS 'n' : le pgm fonctionne bien. - par un 'n' (avec ou sans espace avant, peu importe) : le pgm fonctionne bien. - mais si la dernière ligne est composée uniquement d'espaces suivi OU NON par un 'n' ou bien s'il y a plusieurs lignes d'espaces avec ou sans 'n' à la fin : le pgm boucle indéfiniment. Et c'est ce dernier cas qui pose un problème : le programme boucle indéfiniment sur cette fin de fichier (lignes de code commentées en majuscules) Comment procéder pour que le programme fonctionne quelque soit la dernière ligne?
Il y a plusieurs fonctions de lecture dans ton code. Chacune peut tomber sur un EOF. Le test doit êtr fait à chaque fois.
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(), et de chercher '9' avec strstr()...
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
In 'fr.comp.lang.c', Michel <pas_de_spam> wrote:
Mais je rencontre un problème en fonction de la fin du fichier qui peut
être n'importe quoi, c'est à dire que la dernière ligne du fichier peut
se terminer par n'importe quoi, exemples :
- par une série d'espaces SANS 'n' : le pgm fonctionne bien.
- par un 'n' (avec ou sans espace avant, peu importe) : le pgm
fonctionne bien.
- mais si la dernière ligne est composée uniquement d'espaces suivi OU
NON par un 'n' ou bien s'il y a plusieurs lignes d'espaces avec ou sans
'n' à la fin : le pgm boucle indéfiniment.
Et c'est ce dernier cas qui pose un problème : le programme boucle
indéfiniment sur cette fin de fichier (lignes de code commentées en
majuscules)
Comment procéder pour que le programme fonctionne quelque soit la
dernière ligne?
Il y a plusieurs fonctions de lecture dans ton code. Chacune peut tomber sur
un EOF. Le test doit êtr fait à chaque fois.
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(),
et de chercher '9' avec strstr()...
--
-ed- emdelYOURBRA@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Mais je rencontre un problème en fonction de la fin du fichier qui peut être n'importe quoi, c'est à dire que la dernière ligne du fichier peut se terminer par n'importe quoi, exemples : - par une série d'espaces SANS 'n' : le pgm fonctionne bien. - par un 'n' (avec ou sans espace avant, peu importe) : le pgm fonctionne bien. - mais si la dernière ligne est composée uniquement d'espaces suivi OU NON par un 'n' ou bien s'il y a plusieurs lignes d'espaces avec ou sans 'n' à la fin : le pgm boucle indéfiniment. Et c'est ce dernier cas qui pose un problème : le programme boucle indéfiniment sur cette fin de fichier (lignes de code commentées en majuscules) Comment procéder pour que le programme fonctionne quelque soit la dernière ligne?
Il y a plusieurs fonctions de lecture dans ton code. Chacune peut tomber sur un EOF. Le test doit êtr fait à chaque fois.
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(), et de chercher '9' avec strstr()...
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Michel
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(), et de chercher '9' avec strstr()...
strchr plutôt, car je dois rechercher un char (qui sera le début d'une chaine, certe)?
Effectivement, j'avais pensé lire ligne après ligne par fgets mais comme elles sont relativement longues et que je n'ai besoin d'extraire que des infos situées en - presque - début de ligne, je n'avais pas voulu consommer de la mémoire inutilement. Depuis, je me suis ravisé et je poste mon nouveau code qui fonctionne dans tous les cas cette fois-ci. Peut-être que quelqu'un y décèlera des bug 'cachés', notamment avec les pointeurs qui sont très utilisés. Merci d'avance. Michel
/* lecture des lignes */ while(fgets(ligneLue, TAILLE_LIGNE, pFichierSource) != NULL) { i = 0; l = 0; pCaractereTrouve = NULL; idNonStocke = FAUX;
/* on recherche le premier '9' de la ligne */ if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL) break;
else { /* on le mémorise */ identifiantLu[i++] = *pCaractereTrouve++;
/* on mémorise les 6 caractères suivants */ while(*pCaractereTrouve != ' ' && l++ < 6) identifiantLu[i++] = *pCaractereTrouve++; }
/* on ajoute le caractère de fin de chaîne */ identifiantLu[i] = ' ';
/* on vérifie si le contenu de identifiantLu est déjà stocké */ if(j >= 1) { for(k = 0; k < j; k++) { if(strcmp(pTabIdPub[k], identifiantLu)) idNonStocke = VRAI; } }
if(j <= 1 || idNonStocke == VRAI) { /* on réserve de la mémoire pour un pointeur vers char */ if((pTabIdPub = realloc(pTabIdPub, sizeof(char*) * (j+1))) = NULL) { printf("n"); printf("Module "%s"nLigne %d : echec d'allocation memoire par "realloc".n" "Le programme ne peut continuer.nn", NOM_MODULE, __LINE__); printf("Pressez <enter> pour quitter le programme."); fflush(stdout); getchar(); exit(EXIT_FAILURE); }
/* on mémorise l'id trouvé */ if((pTabIdPub[j] = strdup(identifiantLu)) == NULL) { printf("n"); printf("Module "%s"nLigne %d : echec d'allocation memoire par "strdup".n" "Le programme ne peut continuer.nn", NOM_MODULE, __LINE__); printf("Pressez <enter> pour quitter le programme."); fflush(stdout); getchar(); exit(EXIT_FAILURE); } } j++; }
/* on trie le tableau de données : à faire */ //qsort(
/* affichage des lignes stockées */ for(k = 0; k < j; k++) printf("Ligne n. %04d : %sn", k + 1, pTabIdPub[k]);
/* valorisation des champs de la structure */ InfosFichier_t.pTabIdPub = pTabIdPub; InfosFichier_t.nbElement = j;
return pInfosFichier_t; }
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(),
et de chercher '9' avec strstr()...
strchr plutôt, car je dois rechercher un char (qui sera le début d'une
chaine, certe)?
Effectivement, j'avais pensé lire ligne après ligne par fgets mais comme
elles sont relativement longues et que je n'ai besoin d'extraire que
des infos situées en - presque - début de ligne, je n'avais pas voulu
consommer de la mémoire inutilement.
Depuis, je me suis ravisé et je poste mon nouveau code qui fonctionne
dans tous les cas cette fois-ci.
Peut-être que quelqu'un y décèlera des bug 'cachés', notamment avec les
pointeurs qui sont très utilisés.
Merci d'avance.
Michel
/* lecture des lignes */
while(fgets(ligneLue, TAILLE_LIGNE, pFichierSource) != NULL) {
i = 0;
l = 0;
pCaractereTrouve = NULL;
idNonStocke = FAUX;
/* on recherche le premier '9' de la ligne */
if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL)
break;
else {
/* on le mémorise */
identifiantLu[i++] = *pCaractereTrouve++;
/* on mémorise les 6 caractères suivants */
while(*pCaractereTrouve != ' ' && l++ < 6)
identifiantLu[i++] = *pCaractereTrouve++;
}
/* on ajoute le caractère de fin de chaîne */
identifiantLu[i] = ' ';
/* on vérifie si le contenu de identifiantLu est déjà stocké */
if(j >= 1) {
for(k = 0; k < j; k++) {
if(strcmp(pTabIdPub[k], identifiantLu))
idNonStocke = VRAI;
}
}
if(j <= 1 || idNonStocke == VRAI) {
/* on réserve de la mémoire pour un pointeur vers char */
if((pTabIdPub = realloc(pTabIdPub, sizeof(char*) * (j+1))) = NULL) {
printf("n");
printf("Module "%s"nLigne %d : echec d'allocation memoire
par "realloc".n"
"Le programme ne peut continuer.nn",
NOM_MODULE, __LINE__);
printf("Pressez <enter> pour quitter le programme.");
fflush(stdout);
getchar();
exit(EXIT_FAILURE);
}
/* on mémorise l'id trouvé */
if((pTabIdPub[j] = strdup(identifiantLu)) == NULL) {
printf("n");
printf("Module "%s"nLigne %d : echec d'allocation
memoire par "strdup".n"
"Le programme ne peut continuer.nn", NOM_MODULE,
__LINE__);
printf("Pressez <enter> pour quitter le programme.");
fflush(stdout);
getchar();
exit(EXIT_FAILURE);
}
}
j++;
}
/* on trie le tableau de données : à faire */
//qsort(
/* affichage des lignes stockées */
for(k = 0; k < j; k++)
printf("Ligne n. %04d : %sn", k + 1, pTabIdPub[k]);
/* valorisation des champs de la structure */
InfosFichier_t.pTabIdPub = pTabIdPub;
InfosFichier_t.nbElement = j;
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(), et de chercher '9' avec strstr()...
strchr plutôt, car je dois rechercher un char (qui sera le début d'une chaine, certe)?
Effectivement, j'avais pensé lire ligne après ligne par fgets mais comme elles sont relativement longues et que je n'ai besoin d'extraire que des infos situées en - presque - début de ligne, je n'avais pas voulu consommer de la mémoire inutilement. Depuis, je me suis ravisé et je poste mon nouveau code qui fonctionne dans tous les cas cette fois-ci. Peut-être que quelqu'un y décèlera des bug 'cachés', notamment avec les pointeurs qui sont très utilisés. Merci d'avance. Michel
/* lecture des lignes */ while(fgets(ligneLue, TAILLE_LIGNE, pFichierSource) != NULL) { i = 0; l = 0; pCaractereTrouve = NULL; idNonStocke = FAUX;
/* on recherche le premier '9' de la ligne */ if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL) break;
else { /* on le mémorise */ identifiantLu[i++] = *pCaractereTrouve++;
/* on mémorise les 6 caractères suivants */ while(*pCaractereTrouve != ' ' && l++ < 6) identifiantLu[i++] = *pCaractereTrouve++; }
/* on ajoute le caractère de fin de chaîne */ identifiantLu[i] = ' ';
/* on vérifie si le contenu de identifiantLu est déjà stocké */ if(j >= 1) { for(k = 0; k < j; k++) { if(strcmp(pTabIdPub[k], identifiantLu)) idNonStocke = VRAI; } }
if(j <= 1 || idNonStocke == VRAI) { /* on réserve de la mémoire pour un pointeur vers char */ if((pTabIdPub = realloc(pTabIdPub, sizeof(char*) * (j+1))) = NULL) { printf("n"); printf("Module "%s"nLigne %d : echec d'allocation memoire par "realloc".n" "Le programme ne peut continuer.nn", NOM_MODULE, __LINE__); printf("Pressez <enter> pour quitter le programme."); fflush(stdout); getchar(); exit(EXIT_FAILURE); }
/* on mémorise l'id trouvé */ if((pTabIdPub[j] = strdup(identifiantLu)) == NULL) { printf("n"); printf("Module "%s"nLigne %d : echec d'allocation memoire par "strdup".n" "Le programme ne peut continuer.nn", NOM_MODULE, __LINE__); printf("Pressez <enter> pour quitter le programme."); fflush(stdout); getchar(); exit(EXIT_FAILURE); } } j++; }
/* on trie le tableau de données : à faire */ //qsort(
/* affichage des lignes stockées */ for(k = 0; k < j; k++) printf("Ligne n. %04d : %sn", k + 1, pTabIdPub[k]);
/* valorisation des champs de la structure */ InfosFichier_t.pTabIdPub = pTabIdPub; InfosFichier_t.nbElement = j;
return pInfosFichier_t; }
Michel
/* on recherche le premier '9' de la ligne */ if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL) break;
oups, je viens de me rendre compte que ce break n'a absoluement rien a faire là. Une instruction vide devrait suffire. Michel
/* on recherche le premier '9' de la ligne */
if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL)
break;
oups, je viens de me rendre compte que ce break n'a absoluement rien a
faire là.
Une instruction vide devrait suffire.
Michel
/* on recherche le premier '9' de la ligne */ if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL) break;
oups, je viens de me rendre compte que ce break n'a absoluement rien a faire là. Une instruction vide devrait suffire. Michel
Bruno Desthuilliers
Michel wrote:
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(), et de chercher '9' avec strstr()...
strchr plutôt, car je dois rechercher un char (qui sera le début d'une chaine, certe)?
Effectivement, j'avais pensé lire ligne après ligne par fgets mais comme elles sont relativement longues et que je n'ai besoin d'extraire que des infos situées en - presque - début de ligne, je n'avais pas voulu consommer de la mémoire inutilement.
"Premature optimisation is the root of all evil..."
Bruno
Michel wrote:
AMA, il serait beucoup plus simple de traiter ligne par ligne avec
fgets(), et de chercher '9' avec strstr()...
strchr plutôt, car je dois rechercher un char (qui sera le début d'une
chaine, certe)?
Effectivement, j'avais pensé lire ligne après ligne par fgets mais comme
elles sont relativement longues et que je n'ai besoin d'extraire que
des infos situées en - presque - début de ligne, je n'avais pas voulu
consommer de la mémoire inutilement.
"Premature optimisation is the root of all evil..."
AMA, il serait beucoup plus simple de traiter ligne par ligne avec fgets(), et de chercher '9' avec strstr()...
strchr plutôt, car je dois rechercher un char (qui sera le début d'une chaine, certe)?
Effectivement, j'avais pensé lire ligne après ligne par fgets mais comme elles sont relativement longues et que je n'ai besoin d'extraire que des infos situées en - presque - début de ligne, je n'avais pas voulu consommer de la mémoire inutilement.
"Premature optimisation is the root of all evil..."
Bruno
Michel
"Premature optimisation is the root of all evil..."
Soit! Michel, vive la RAM pas chère...
"Premature optimisation is the root of all evil..."
"Premature optimisation is the root of all evil..."
pour mon info, c'est une citation de qui?
arf google m'a répondu! au fait s/optimisation/optimization
<PAQJS> ... les deux orthographes sont acceptables, la seconde ('z') étant plus spécialement US </PAQJS>
Gabriel Dos Reis
Pascal writes:
| Pascal wrote: | | > Bruno Desthuilliers wrote: | > | >> "Premature optimisation is the root of all evil..." | > pour mon info, c'est une citation de qui? | | arf google m'a répondu! au fait s/optimisation/optimization
optimisation est british et optimisation est american.
-- Gaby
Pascal <fuck@versign.com> writes:
| Pascal wrote:
|
| > Bruno Desthuilliers wrote:
| >
| >> "Premature optimisation is the root of all evil..."
| > pour mon info, c'est une citation de qui?
|
| arf google m'a répondu! au fait s/optimisation/optimization
optimisation est british et optimisation est american.
| Pascal wrote: | | > Bruno Desthuilliers wrote: | > | >> "Premature optimisation is the root of all evil..." | > pour mon info, c'est une citation de qui? | | arf google m'a répondu! au fait s/optimisation/optimization
optimisation est british et optimisation est american.
-- Gaby
Marc Lasson
Michel wrote:
/* on recherche le premier '9' de la ligne */ if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL) break;
oups, je viens de me rendre compte que ce break n'a absoluement rien a faire là. Une instruction vide devrait suffire.
Moué, c'est un peu capilotracté: if (A) {/* rien */} else {quelquechose();}
C'est un peu equivalent à :
if (!A) {quelquechose();}
-- Marc.
Michel wrote:
/* on recherche le premier '9' de la ligne */
if((pCaractereTrouve = strchr(ligneLue, '9')) == NULL)
break;
oups, je viens de me rendre compte que ce break n'a absoluement rien a
faire là.
Une instruction vide devrait suffire.
Moué, c'est un peu capilotracté:
if (A) {/* rien */} else {quelquechose();}