Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
916 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Problème d'affichage dans le résultat de ma fonction C

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Problème d'affichage dans le résultat de ma fonction C

n°2271097
simon91
Posté le 08-12-2015 à 16:08:54  profilanswer
 

Bonjour,
J'ai un problème avec mon programme C qui a pour but de lire et d'afficher le contenu d'un fichier qui contient plusieurs adresses. Les adresses sont représentées d'une manière verticale sur une seule colonne pour faciliter au programme sa lecture.
Lorsque par exemple le nom de la voie est composé de plusieurs mots, le programme ne me l'affiche pas correctement.
Voici mon code :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef struct adresse Adresse;
  5. struct adresse {char *num; char *voie; char *nomVoie; char *ville; char *codPostale;};
  6. int main(void) {
  7. int n = 0;
  8. int i;
  9. struct adresse *Adresse = NULL;
  10.     FILE *f = fopen("fichier.txt","r" );
  11.     if (!f) {
  12.         printf("Impossible d'ouvrir le fichier\n" );
  13.         return 1;
  14.     }
  15.     char ligne[256];
  16.     while (fgets(ligne,256,f)) {
  17.         Adresse = realloc(Adresse, sizeof(struct adresse)*(n+1));
  18.     if (!Adresse) {
  19.          printf("out of memory\n" );
  20.          exit(1);
  21.     }
  22. Adresse[n].num = malloc( 256*sizeof( char));
  23. Adresse[n].voie = malloc( 256*sizeof( char));
  24. Adresse[n].nomVoie = malloc( 256*sizeof( char));
  25. Adresse[n].ville = malloc( 256*sizeof( char));
  26. Adresse[n].codPostale = malloc( 256*sizeof( char));
  27. fscanf( f , "%s %s %s %s %s", Adresse[n].num, Adresse[n].voie, Adresse[n].nomVoie, Adresse[n].ville ,Adresse[n].codPostale);
  28. n++; 
  29.     }
  30.   fclose(f);
  31.     for (i = 0; i < n; i++)
  32.     {
  33.  printf("\nNuméro : %s \n", Adresse[i].num);
  34.  printf("\nVoie : %s \n", Adresse[i].voie);
  35.  printf("\nNom de la voie :%s \n", Adresse[i].nomVoie);
  36.  printf("\nVille :%s \n", Adresse[i].ville);
  37.  printf("\nCode postale : %s \n", Adresse[i].codPostale);
  38.    
  39.     }
  40.     return 0;
  41. }


 
Par exemple pour un fichier contenant ces adresses:
5
rue
Paul Froment
Paris  
75001
2
allée
Pierre Gaspard
Paris
75019
 
J'ai ce résultat:
 
Numéro : 5  
Voie : rue  
Nom de la voie : Paul  
Ville :Froment  
Code postale : Paris  
Numéro : 75001  
Voie : 2  
Nom de la voie :allée  
Ville : Pierre  
Code postale : Gaspard  
Numéro : Paris  
Voie : 75019  
Nom de la voie :  
Ville :  
 
Comment puis je procéder pour remédier à ce problème ?
 
Merci d'avance pour l'aide.
 
 

mood
Publicité
Posté le 08-12-2015 à 16:08:54  profilanswer
 

n°2271098
TotalRecal​l
Posté le 08-12-2015 à 16:19:45  profilanswer
 

fscanf( f , "%s %s %s %s %s", ...) ça ne ferait pas par hasard la rupture entre chaque élément sur les espaces ? :whistle:

 

Conclusion tu dois revoir ta méthode de lecture...

Message cité 1 fois
Message édité par TotalRecall le 08-12-2015 à 16:20:46

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271099
simon91
Posté le 08-12-2015 à 16:23:15  profilanswer
 

TotalRecall a écrit :

fscanf( f , "%s %s %s %s %s", ...) ça ne ferait pas par hasard la rupture entre chaque élément sur les espaces ? :whistle:
 
Conclusion tu dois revoir ta méthode de lecture...


 
C'est justement l'objet de mon post, je voudrais de l'aide par rapport à cela

n°2271102
TotalRecal​l
Posté le 08-12-2015 à 16:37:08  profilanswer
 

Ben par exemple :
Lecture ligne par ligne, si l'ordre est constant et le nombre d'éléments par adresse fixe.
Ou détection des lignes vides pour faire la rupture entre chaque adresse (préférable de tte façon en cas d'erreur dans le fichier)

 

Trouver comment faire de la lecture par ligne en C c'est pas bien compliqué, après y a plus qu'à écrire l'algo [:spamafote]

Message cité 1 fois
Message édité par TotalRecall le 08-12-2015 à 16:37:42

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271103
simon91
Posté le 08-12-2015 à 16:42:06  profilanswer
 

TotalRecall a écrit :

Ben par exemple :
Lecture ligne par ligne, si l'ordre est constant et le nombre d'éléments par adresse fixe.  
Ou détection des lignes vides pour faire la rupture entre chaque adresse (préférable de tte façon en cas d'erreur dans le fichier)
 
Trouver comment faire de la lecture par ligne en C c'est pas bien compliqué, après y a plus qu'à écrire l'algo [:spamafote]


 
L'odre est constant mais le nombre d'éléments par adresses est fixe.
Peux tu me donner une réponse un peu plus précise avec un exemple stp ? ça m'aiderait de beaucoup pour la compréhension. Là je trouve que les réponses sont un peu vagues du coup je ne sais pas trop par ou commencer. Merci

n°2271104
TotalRecal​l
Posté le 08-12-2015 à 16:57:44  profilanswer
 

J'ai pas fait de C depuis 15 ans, je préviens :o

 

Mais tu peux utiliser une fonction comme "fgets", qui prend un pointeur vers ton fichier, une longueur de buffer, et un buffer.
Je te laisse regarder comment ça s'utilise. Si t'as pu écrire ton code ci-dessus ça ne devrait pas te poser de difficulté !

 

Tu boucles dessus 11 fois (puisque tes adresses ont 10 lignes, la 11e sera soit une ligne vide soit la fin du fichier, sinon y a un pb)
Au cours de ta boucle tu te débrouilles pour assigner (en fonction de l'index de la boucle) le champ correspondant de l'adresse.
Attention, fgets ramène tout le contenu de la ligne, y compris le \r et/ou \n il me semble.

 

Y a ss doute quelques milliers d'autres façons de faire mais c'en est toujours une.

 

edit : tiens je viens de voir que tu as déjà utilisé fgets dans ton programme. Ca va faciliter les choses :D. C'est donc bien qu'une question d'algo au final, et la mauvaise utilisation de fscanf...

Message cité 1 fois
Message édité par TotalRecall le 08-12-2015 à 17:00:31

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271109
simon91
Posté le 08-12-2015 à 17:49:46  profilanswer
 

TotalRecall a écrit :

J'ai pas fait de C depuis 15 ans, je préviens :o
 
Mais tu peux utiliser une fonction comme "fgets", qui prend un pointeur vers ton fichier, une longueur de buffer, et un buffer.
Je te laisse regarder comment ça s'utilise. Si t'as pu écrire ton code ci-dessus ça ne devrait pas te poser de difficulté !
 
Tu boucles dessus 11 fois (puisque tes adresses ont 10 lignes, la 11e sera soit une ligne vide soit la fin du fichier, sinon y a un pb)
Au cours de ta boucle tu te débrouilles pour assigner (en fonction de l'index de la boucle) le champ correspondant de l'adresse.
Attention, fgets ramène tout le contenu de la ligne, y compris le \r et/ou \n il me semble.  
 
Y a ss doute quelques milliers d'autres façons de faire mais c'en est toujours une.
 
edit : tiens je viens de voir que tu as déjà utilisé fgets dans ton programme. Ca va faciliter les choses :D. C'est donc bien qu'une question d'algo au final, et la mauvaise utilisation de fscanf...


 
Justement le fgets je l'ai déjà utilisé mais pourquoi il n'arrive pas à prendre toute la ligne ? Comment utiliser au final le scanf ?  
15 ans sans faire le C ouaaw je sais pas si tu pourrais bien m'aider du coup...
 
 
 

n°2271118
gilou
Modérateur
Modzilla
Posté le 08-12-2015 à 19:13:32  profilanswer
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef struct adresse Adresse;
  5. struct adresse {
  6.     char *num;
  7.     char *voie;
  8.     char *nomVoie;
  9.     char *ville;
  10.     char *codPostale;
  11. };
  12. int main(void) {
  13.     int n = 0;
  14.     int i;
  15.     struct adresse *Adresse = NULL;
  16.     FILE *f = fopen("poste.txt","r" );
  17.     if (!f) {
  18.         printf("Impossible d'ouvrir le fichier\n" );
  19.         return 1;
  20.     }
  21.     char buff[5][256];
  22.     while ((fscanf( f , "%[^\n]\n%[^\n]\n%[^\n]\n%[^\n]\n%[^\n]\n", buff[0], buff[1], buff[2], buff[3], buff[4])) == 5) {
  23.         Adresse = realloc(Adresse, sizeof(struct adresse)*(n+1));
  24.         if (!Adresse) {
  25.             printf("out of memory\n" );
  26.             exit(1);
  27.         }
  28.         // Avec votre méthode
  29.         /* Adresse[n].num = malloc( 256*sizeof( char));
  30.         Adresse[n].voie = malloc( 256*sizeof( char));
  31.         Adresse[n].nomVoie = malloc( 256*sizeof( char));
  32.         Adresse[n].ville = malloc( 256*sizeof( char));
  33.         Adresse[n].codPostale = malloc( 256*sizeof( char));
  34.         strncpy(Adresse[n].num, buff[0], 256);
  35.         strncpy(Adresse[n].voie, buff[1], 256);
  36.         strncpy(Adresse[n].nomVoie, buff[2], 256);
  37.         strncpy(Adresse[n].ville, buff[3], 256);
  38.         strncpy(Adresse[n].codPostale, buff[4], 256);*/
  39.         // Méthode qui n'alloue que ce qu'il faut
  40.         Adresse[n].num = strdup(buff[0]);
  41.         Adresse[n].voie = strdup(buff[1]);
  42.         Adresse[n].nomVoie = strdup(buff[2]);
  43.         Adresse[n].ville = strdup(buff[3]);
  44.         Adresse[n].codPostale = strdup(buff[4]);
  45.         ++n;
  46.     }
  47.     fclose(f);
  48.     for (i = 0; i < n; ++i) {
  49.         printf("Numéro : %s \n", Adresse[i].num);
  50.         printf("Voie : %s \n", Adresse[i].voie);
  51.         printf("Nom de la voie : %s \n", Adresse[i].nomVoie);
  52.         printf("Ville : %s \n", Adresse[i].ville);
  53.         printf("Code postale : %s \n", Adresse[i].codPostale);
  54.         printf("\n" );
  55.     }
  56.     return 0;
  57. }


(fscanf( f , "%[^\n]\n%[^\n]\n%[^\n]\n%[^\n]\n%[^\n]\n", buff[0], buff[1], buff[2], buff[3], buff[4])) == 5
fscan va scanner en prenant d'un coup tout ce qui n'est pas un \n: %[^\n], suivi d'un \n et s'il n'en trouve pas 5 de suite, on a un échec.
 
A+,


Message édité par gilou le 08-12-2015 à 19:17:02

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2271120
simon91
Posté le 08-12-2015 à 19:36:37  profilanswer
 


(fscanf( f , "%[^\n]\n%[^\n]\n%[^\n]\n%[^\n]\n%[^\n]\n", buff[0], buff[1], buff[2], buff[3], buff[4])) == 5
fscan va scanner en prenant d'un coup tout ce qui n'est pas un \n: %[^\n], suivi d'un \n et s'il n'en trouve pas 5 de suite, on a un échec.
 
A+,[/quotemsg]
 
Merci Gilou je suis soulagé, il me manquait vraiment cette ligne pour résoudre mon problème ;)

n°2271121
gilou
Modérateur
Modzilla
Posté le 08-12-2015 à 19:56:38  profilanswer
 

Noter que ce genre de manip est très hasardeuse, sauf avec du texte déjà formaté par un programme et dont on sait qu'il est 100% conforme à une spec.
Ça ne marchera pas si une ligne est vide par exemple, ça décalera le tout.
 
En y repensant,  
while ((fscanf( f , " %[^\n] %[^\n] %[^\n] %[^\n] %[^\n]", buff[0], buff[1], buff[2], buff[3], buff[4])) == 5) {
serait préférable comme forme:
le blanc initial va bouffer un \n éventuel de la fin de ligne précédente, et le code fonctionnera que la dernière ligne ait un \n final ou pas.
 
Et en y repensant à deux fois,
while ((fscanf( f , "%[^\n] %[^\n] %[^\n] %[^\n] %[^\n] ", buff[0], buff[1], buff[2], buff[3], buff[4])) == 5) {
ou le blanc final bouffera le \n de fin de ligne s'il est présent est sans doute encore mieux, car plus lisible.  
 
A+,

Message cité 1 fois
Message édité par gilou le 08-12-2015 à 20:00:12

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
mood
Publicité
Posté le 08-12-2015 à 19:56:38  profilanswer
 

n°2271122
simon91
Posté le 08-12-2015 à 20:02:47  profilanswer
 

gilou a écrit :

Noter que ce genre de manip est très hasardeuse, sauf avec du texte déjà formaté par un programme et dont on sait qu'il est 100% conforme à une spec.
Ça ne marchera pas si une ligne est vide par exemple, ça décalera le tout.
 
En y repensant,  
while ((fscanf( f , " %[^\n] %[^\n] %[^\n] %[^\n] %[^\n]", buff[0], buff[1], buff[2], buff[3], buff[4])) == 5) {
serait préférable comme forme:
le blanc initial va bouffer un \n éventuel de la fin de ligne précédente, et le code fonctionnera que la dernière ligne ait un \n final ou pas.
 
Et en y repensant à deux fois,
while ((fscanf( f , "%[^\n] %[^\n] %[^\n] %[^\n] %[^\n] ", buff[0], buff[1], buff[2], buff[3], buff[4])) == 5) {
ou le blanc final bouffera le \n de fin de ligne s'il est présent est sans doute encore mieux, car plus lisible.  
 
A+,


 
Ok c'est noté merci pour la précision  :)

n°2271156
TotalRecal​l
Posté le 09-12-2015 à 09:14:33  profilanswer
 

Je n'ai pas voulu suggérer le fscanf sur %[^\n]\n parce qu'effectivement si le fichier a une anomalie ça risque d'être le bordel pour récupérer le coup...


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271164
simon91
Posté le 09-12-2015 à 09:53:12  profilanswer
 

TotalRecall a écrit :

Je n'ai pas voulu suggérer le fscanf sur %[^\n]\n parce qu'effectivement si le fichier a une anomalie ça risque d'être le bordel pour récupérer le coup...


 
Ah d'accord je vois ;)

n°2271190
gilou
Modérateur
Modzilla
Posté le 09-12-2015 à 11:52:10  profilanswer
 

Oui, si on veut une version plus blindée, il faut passer par du fgets.
Je posterai cela tout à l'heure, mais la, c'est rasage + douche.
Question à 10 balles: c'était nécessaire d'écrire ça en C? en perl, ça m'aurait pris 3 mn.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2271195
TotalRecal​l
Posté le 09-12-2015 à 12:01:51  profilanswer
 

Je dirai que ça sent l'exercice scolaire :d


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271202
simon91
Posté le 09-12-2015 à 12:22:59  profilanswer
 

gilou a écrit :

Oui, si on veut une version plus blindée, il faut passer par du fgets.
Je posterai cela tout à l'heure, mais la, c'est rasage + douche.
Question à 10 balles: c'était nécessaire d'écrire ça en C? en perl, ça m'aurait pris 3 mn.
 
A+,


 
Oui en C gilou...

n°2271204
simon91
Posté le 09-12-2015 à 12:54:44  profilanswer
 

gilou a écrit :

Oui, si on veut une version plus blindée, il faut passer par du fgets.
Je posterai cela tout à l'heure, mais la, c'est rasage + douche.
Question à 10 balles: c'était nécessaire d'écrire ça en C? en perl, ça m'aurait pris 3 mn.
 
A+,


 
Par contre s'il s'agissait de lire une liste de nombres dans le fichier et afficher le nombre et son indice tel que:
 
1. 12
 
2. 2.567
 
3. 42.004
 
etc...
 
Comment l'adapterais tu avec ta méthode ?

n°2271216
TotalRecal​l
Posté le 09-12-2015 à 14:21:19  profilanswer
 

Et si tu essayais un peu et tu nous montrais tes résultats ?  
On veut bien aider mais on ne fait pas les devoirs, cf les règles du forum...


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271225
simon91
Posté le 09-12-2015 à 14:33:14  profilanswer
 

TotalRecall a écrit :

Et si tu essayais un peu et tu nous montrais tes résultats ?  
On veut bien aider mais on ne fait pas les devoirs, cf les règles du forum...


 
Je n'ai pas demandé que l'on fasse de devoir à ma place, je bien formulé ma question: 'adapter à avec sa méthode à lui', ce qui voudrait dire que je l'ai fait avec une autre méthode.
Au début de mon post, j'ai bien montré mon travail puis j'ai rencontré une difficulté raison par laquelle j'ai demandé de l'aide.
Si je n'avais aucune volonté je postais directement ce qu'il était demandé à faire sans rien faire.
Ton message n'est pas du tout encourageant pour une personne qui a de la volonté de s'exercer et d'une manière ou d'une autre nous rencontrons tous des difficultés dans l'apprentissage. C'est bien de ces erreurs que nous apprenons avant de pouvoir maitriser.

n°2271228
TotalRecal​l
Posté le 09-12-2015 à 14:35:43  profilanswer
 

Justement, tu as apparemment tous les outils et infos nécessaires, maintenant il faut réfléchir un peu pour adapter à chaque situation.
Lire des adresses ou des nombres c'est un peu pareil...
Si tu essaies et que tu butes sur un souci concret, ou bien si tu dis "j'ai fait ça, qu'est ce que tu en penses ?" c'est une chose, mais si tu dis "et maintenant j'ai ce cas là, est ce que tu peux m'aider Gilou", ça revient à faire faire le travail.


Message édité par TotalRecall le 09-12-2015 à 14:36:58

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271232
gilou
Modérateur
Modzilla
Posté le 09-12-2015 à 14:39:36  profilanswer
 

Un fichier avec seulement des nombres décimaux?
A la base, c'est une variation sur ce thème:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int main(void) {
  5.     FILE *f = fopen("test.txt","r" );
  6.     if (!f) {
  7.         printf("Impossible d'ouvrir le fichier\n" );
  8.         return 1;
  9.     }
  10.    
  11.     double d;
  12.     int n = 1;
  13.     while ((fscanf( f , "%lf", &d)) == 1) {
  14.         printf("%d.\t%g\n", n, d);
  15.         ++n;
  16.     }
  17.     fclose(f);
  18.    
  19.     return 0;
  20. }

Testé sur:

12
 
2.567  15.25
 
 
42.004

Donne en résultat:

1.      12
2.      2.567
3.      15.25
4.      42.004


 
A+,

Message cité 1 fois
Message édité par gilou le 09-12-2015 à 14:41:10

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2271233
TotalRecal​l
Posté le 09-12-2015 à 14:42:03  profilanswer
 

Tu es bien trop serviable gilou, tu devrais être modérateur :o [:vinceboulet]

Message cité 1 fois
Message édité par TotalRecall le 09-12-2015 à 14:42:22

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271237
simon91
Posté le 09-12-2015 à 14:56:31  profilanswer
 

gilou a écrit :

Un fichier avec seulement des nombres décimaux?
A la base, c'est une variation sur ce thème:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int main(void) {
  5.     FILE *f = fopen("test.txt","r" );
  6.     if (!f) {
  7.         printf("Impossible d'ouvrir le fichier\n" );
  8.         return 1;
  9.     }
  10.    
  11.     double d;
  12.     int n = 1;
  13.     while ((fscanf( f , "%lf", &d)) == 1) {
  14.         printf("%d.\t%g\n", n, d);
  15.         ++n;
  16.     }
  17.     fclose(f);
  18.    
  19.     return 0;
  20. }

Testé sur:

12
 
2.567  15.25
 
 
42.004

Donne en résultat:

1.      12
2.      2.567
3.      15.25
4.      42.004


 
A+,


 
 
Merci pour ta collaboration Gilou, c'est sympa. En effet celle que j'ai eu à faire n'était pas bien efficace et surtout généraliste je me rends compte. La tienne est bcp plus limpide ;)

n°2271238
TotalRecal​l
Posté le 09-12-2015 à 14:59:11  profilanswer
 

C'est assez épatant ce que fscanf peut faire. Mais par contre par conception ça n'est pas tolérant aux erreurs si le fichier ne colle pas à ce à quoi tu t'attends.


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271239
simon91
Posté le 09-12-2015 à 15:03:07  profilanswer
 

TotalRecall a écrit :

Tu es bien trop serviable gilou, tu devrais être modérateur :o [:vinceboulet]


 
Pourquoi cela te pose tant de problème ? Le but du forum n'est il pas de demander de l'aide lorsque l'on bute sur un exercice ? En plus je trouve cela bien d'exposer chacun de nos problème car cela permet également à celui qui vient en aide de rencontrer d'autres difficultés pour tester déjà son niveau s'il est en mésure de le résoudre et se perfectionner encore plus.
C'est plutot avantageux dans les deux sens, autant pour celui qui apprend que pour celui qui maitriser.
La révision est la mère des sciences.

n°2271240
simon91
Posté le 09-12-2015 à 15:04:21  profilanswer
 

TotalRecall a écrit :

C'est assez épatant ce que fscanf peut faire. Mais par contre par conception ça n'est pas tolérant aux erreurs si le fichier ne colle pas à ce à quoi tu t'attends.


 
Je me rends compte que c'est aussi bénéfique pour toi en fin de compte ... ;)

n°2271241
TotalRecal​l
Posté le 09-12-2015 à 15:06:04  profilanswer
 

simon91 a écrit :

 

Pourquoi cela te pose tant de problème ? Le but du forum n'est il pas de demander de l'aide lorsque l'on bute sur un exercice ? En plus je trouve cela bien d'exposer chacun de nos problème car cela permet également à celui qui vient en aide de rencontrer d'autres difficultés pour tester déjà son niveau s'il est en mésure de le résoudre et se perfectionner encore plus.
C'est plutot avantageux dans les deux sens, autant pour celui qui apprend que pour celui qui maitriser.
La révision est la mère des sciences.

 

Le smiley " :o " marque en général le second degré, n'y vois pas d'offense !
Et je t'ai dit plus haut ce que je voulais dire : même dans ton propre intérêt, il vaut mieux essayer de trouver toi même des solutions avant de demander le corrigé. Même si ton approche est moins efficace que celle de Gilou c'est toujours plus formateur comme ça.


Message édité par TotalRecall le 09-12-2015 à 15:07:05

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271243
TotalRecal​l
Posté le 09-12-2015 à 15:07:37  profilanswer
 

simon91 a écrit :


 
Je me rends compte que c'est aussi bénéfique pour toi en fin de compte ... ;)


[:sombrero67] ?
J'ai dit que je n'avais pas fait de C depuis 15 ans, pas que je veux m'y mettre  [:korner]


Message édité par TotalRecall le 09-12-2015 à 15:08:23

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2271245
gilou
Modérateur
Modzilla
Posté le 09-12-2015 à 15:12:58  profilanswer
 

TotalRecall a écrit :

C'est assez épatant ce que fscanf peut faire. Mais par contre par conception ça n'est pas tolérant aux erreurs si le fichier ne colle pas à ce à quoi tu t'attends.


Voila pourquoi on peut utiliser fgets pour être tolérant aux pannes ;)  

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef struct adresse Adresse;
  5. struct adresse {
  6.     char *num;
  7.     char *voie;
  8.     char *nomVoie;
  9.     char *ville;
  10.     char *codPostale;
  11. };
  12. int main(void) {
  13.     FILE *f = fopen("poste.txt","r" );
  14.     if (!f) {
  15.         printf("Impossible d'ouvrir le fichier\n" );
  16.         return 1;
  17.     }
  18.     struct adresse *Adresse = NULL;
  19.     int n = 0;
  20.     int i;
  21.     char buff[5][256];
  22.     while (((fgets(buff[0], 256, f)) != NULL) &&
  23.             ((fgets(buff[1], 256, f)) != NULL) &&
  24.             ((fgets(buff[2], 256, f)) != NULL) &&
  25.             ((fgets(buff[3], 256, f)) != NULL) &&
  26.             ((fgets(buff[4], 256, f)) != NULL)) {
  27.         Adresse = realloc(Adresse, sizeof(struct adresse)*(n+1));
  28.         if (!Adresse) {
  29.             printf("out of memory\n" );
  30.             exit(1);
  31.         }
  32.         // virer le \n de fin de ligne
  33.         for (i = 0; i < 5; ++i) {
  34.             int k = strlen(buff[i]);
  35.             if ((k > 0) && (buff[i][k-1] == '\n')) {
  36.                 buff[i][k-1] = '\0';
  37.             }
  38.         }
  39.         Adresse[n].num = strdup(buff[0]);
  40.         Adresse[n].voie = strdup(buff[1]);
  41.         Adresse[n].nomVoie = strdup(buff[2]);
  42.         Adresse[n].ville = strdup(buff[3]);
  43.         Adresse[n].codPostale = strdup(buff[4]);
  44.         ++n;
  45.     }
  46.     fclose(f);
  47.     for (i = 0; i < n; ++i) {
  48.         printf("Numéro : %s \n", Adresse[i].num);
  49.         printf("Voie : %s \n", Adresse[i].voie);
  50.         printf("Nom de la voie : %s \n", Adresse[i].nomVoie);
  51.         printf("Ville : %s \n", Adresse[i].ville);
  52.         printf("Code postale : %s \n", Adresse[i].codPostale);
  53.         printf("\n" );
  54.     }
  55.     return 0;
  56. }


Le seul truc contre lequel ce n'est pas blindé, c'est un fichier avec une ligne de taille > 255 caractères, mais c'est une hypothèse assez raisonnable ici.
Dans cette version la, une ligne vide en entrée sera comprise comme un champ vide.
 
A+,


Message édité par gilou le 09-12-2015 à 15:14:28

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2271336
simon91
Posté le 10-12-2015 à 12:42:15  profilanswer
 


Le seul truc contre lequel ce n'est pas blindé, c'est un fichier avec une ligne de taille > 255 caractères, mais c'est une hypothèse assez raisonnable ici.
Dans cette version la, une ligne vide en entrée sera comprise comme un champ vide.
 
A+
 
Ok merci Gilou, je pense que cette version n'est pas très différente de la première mais apparement bcp plus efficace ;)

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Problème d'affichage dans le résultat de ma fonction C

 

Sujets relatifs
Powershell - Problème script création d'utilisateur dans l'ADprobleme de décimal -Java
Problème intent.putExtraproblème while
Problème d'impression de fichier html contenant un saut de pageSouci pour exécuter fonction ajax au chargement de la page
Problème bouton menu mobile[JAVA]probleme de bouton personnaliser.
[JQUERY]Problème requête ajax en GET via PHP[C] parcours en largeur \ profondeur
Plus de sujets relatifs à : [C] Problème d'affichage dans le résultat de ma fonction C


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR