Se connecter / S'enregistrer
Votre question

Problème écriture dans un fichier en language C

Tags :
  • Programmation
Dernière réponse : dans Programmation
11 Avril 2008 18:41:45

Bonjours à tous,

  1. void SaisirClient(int i)
  2. {
  3. char Identifiant[9];
  4.  
  5. FILE *fichier;
  6.  
  7. if ((fichier = fopen("annuaire.txt", "r")) == NULL)
  8. {
  9. printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n");
  10. exit(1);
  11. }
  12.  
  13. system("CLS");
  14. printf (" Saisie du %d ieme Client: \n", i + 1 );
  15.  
  16. printf ("\n Entrez l'identifiant: ");
  17. scanf ("%s", &ListeClient[i].Identifiant);
  18. while(fscanf(fichier,"\n%[^*]*", &Identifiant)!=EOF) // tant que la fin du fichier n'est pas atteint
  19. {
  20. if(strcmp(Identifiant, ListeClient[0].Identifiant)==0)
  21. {
  22. printf ("\n Erreur: l'Identifiant existe deja. Recommencez: ");
  23. scanf ("%s", &ListeClient[i].Identifiant);
  24. }
  25. } // fin du while
  26. fclose(fichier);
  27.  
  28. }


  1. void Enregistrement(int NbreClients)
  2. {
  3. char str[8];
  4. char chainefic[1000];
  5. int index;
  6. int k;
  7. int lg,i;
  8. char newline[2]= "\n";
  9.  
  10. FILE *files;
  11.  
  12. if ((files = fopen("annuaire.txt", "a")) == NULL)
  13. {
  14. printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n");
  15. exit(1);
  16. }
  17. for(i=0; i < NbreClients; i++)
  18. {
  19. //instruction longue donc je vous la met pas
  20. }
  21. fclose(files);
  22. }


dans le main(), sa ce présente comme ça:
  1. for (i = 0; i < NbreClients; i++)
  2. {
  3. SaisirClient(i);
  4. }
  5.  
  6. Enregistrement(NbreClients);



Donc voila mon problème que je rencontre avec ces deux fonction, je saisie des information que je veux ensuite enregistrer dans le fichier annuaire.txt, seulement sa ne fonctionne que si il n'y a rien dans le fichier, si j'ai déjà saisie des info avant, windows me met un message d'erreur du genre:
"Annuaire.exe a rencontré un problème et doit fermer. Nous vous prions de nous excuser pour le désagrément encouru."

Je pense que le problème vient de fait que j'utilise deux fois d'affillé FILE* fichier, fichier = fopen(....). Mais je n'arrive pas a comprendre pourquoi.
Qu'es ce que vous en pensez?

Merci d'avance pour vos réponse

Autres pages sur : probleme ecriture fichier language

a b L Programmation
11 Avril 2008 20:33:06

C'est ton programme qui crash.
Le FILE * ne pose pas de problème, d'autant que tu fermes bien le fichier.

Ton problème vient d'ailleurs. Lorsque tu enregistres en fin de fichier, as-tu déjà chargé des données ?

Sinon, passe en debug pour savoir où ça plante exactement.
Probablement un pointeur qui, quelque part, n'est pas NULL, ce qui donne un pointeur invalide sur la mémoire hors de ton processus.
11 Avril 2008 20:38:56

Merci d'avoir répondu aussi rapidement, je vais voir dans ce sens.
Contenus similaires
11 Avril 2008 20:41:27

A oui j'ai oublié de précisais que lorsque je retire le FILE *fichier et le fichier = fopen(...) enfin tous ce qui permet de lire le fichier dans la fonction saisie et bien sa fonctionne très bien, c'est pour sa que je pensais que ça venais de la.
a b L Programmation
11 Avril 2008 20:58:06

Non, c'est lorsque tu lis le fichier, tu ne remplis pas correctement tous les champs.
Est-ce que tous chaines sont correctement taillées (que ce soit statiquement ou dynamiquement), en prenant bien en compte le '\0' terminal de toute chaine de caractères. Si tu as des liens (comme pour les listes chainées), pour touts les liens non utilisés, force-les bien à 0.
Lorsque tu prends le contenu d'un pointeur, vérifie bien que tu fais un test de pointeur non nul.
11 Avril 2008 21:15:25

Désolé mais je n'ai pas tout compris. Oui toute mes chaine de caractère sont bien taillé j'ai fait attention mais qu'es ce que tu entend par statiquement et dynamiquement? Et finissent bien par \0.
11 Avril 2008 21:39:02

En débugant, j'ai trouvé le problème mais je sais pas comment le résoudre!
le problème vient de la:

1. for (i = 0; i < NbreClients; i++)
2. {
3. SaisirClient(i);
4. }
5.
6. Enregistrement(NbreClients);

Par exemple, je rentre comme valeur 1 pour NbreClient (le code pour cette saisie n'est pas affiché), donc il fait la boucle for une fois puis passe a la fonction Enregistrement mais le problème c'est que lorsqu'il passe a cette fonction, NbreClient = 2293560 mais je sais pas pourquoi et donc après dans cette fonction il y a une boucle for qui dépend de NbreClient et donc il fait la boucle 2293560 fois. Quand je débug il me met un message: Une violation d'accès (erreur de segmentation) est apparue dans votre programme.
Anonyme
11 Avril 2008 23:33:24

si tu pouvais faire un printf de NbreClients avant le for qui est dans Enregistrement.. parce que c'est louche
dans le for qui boucle tu modifies NbreClient ?
a b L Programmation
12 Avril 2008 07:56:28

Je pense qu'il le modifie indirectement en écrasant la pile par un buffer overflow en modifiant une variable globale.
seb326 tu ferai mieux de montrer tout ton code, parce que le problème peut être partout, et probablement à l'initialisation de tes structures.
12 Avril 2008 09:51:16

Je veux bien mettre tout mon code mais il fait 700 lignes!!

Cart: Non je modifie jamais NbreClient, d'ailleurs dans saisieClient NbreClient n'est pas utilisé.
12 Avril 2008 10:03:50

Voici mon code, j'ai quand même retiré des fonctions car je pense pas que sa vient de celles ci puisqu'elle sont indépendantes des autres.
(fonctions retiré: Lister(), Modifier(Client *cellule), Supprimer(), Rechercher())
Merci d'avance pour ceux qui essayeront de comprendre mon code.

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <ctype.h>
  5. #include <string.h>
  6. #include <windows.h>
  7. #include <time.h>
  8.  
  9. #define DIM_ID 9
  10. #define DIM_LISTE 5
  11. #define DIM_CHAINE 40
  12. #define DIM_NUMTEL 15
  13. #define DIM_CP 6 //6 pas 5 car \o fin de chaine de caractere
  14. #define DIM_NUM 7 // car il peut y avoir des bis,ter...
  15. #define DIM_DATE 30
  16. #define VRAI 1
  17. #define FAUX 0
  18. #define LGMAX 1000
  19. #define TAILLE_MAX 1000
  20.  
  21. // Definition de la structure nommée Adresse
  22. typedef struct Adresse
  23. {
  24. char Num[DIM_NUM];
  25. char Rue[DIM_CHAINE];
  26. char CodePostal[DIM_CP] ;
  27. }Adresse ;
  28.  
  29. // Definition de la structure nommée Client
  30. typedef struct Client
  31. {
  32. char Identifiant[DIM_ID];
  33. char NomEnt[DIM_CHAINE];
  34. struct Adresse AdrEnt_Cli;
  35. char NomCli[DIM_CHAINE];
  36. char PrenomCli[DIM_CHAINE];
  37. char MailCli[DIM_CHAINE];
  38. char TelCli[DIM_NUMTEL];
  39. char Date[DIM_DATE];
  40. }Client ;
  41.  
  42. Client ListeClient[DIM_LISTE];
  43.  
  44.  
  45. Adresse LireAdresse ();
  46.  
  47.  
  48.  
  49. void AfficheClient(Client *cellule)
  50. {
  51. time_t t = time(NULL);
  52. srand( time(NULL) );
  53. time(&t);
  54. printf ("\n Identifiant : %s", cellule->Identifiant);
  55. printf ("\n Nom de l'entreprise : %s", cellule->NomEnt);
  56. printf ("\n Adresse : %s, %s %s", cellule->AdrEnt_Cli.Num,cellule->AdrEnt_Cli.Rue,cellule->AdrEnt_Cli.CodePostal);
  57. printf ("\n Nom du Client : %s", cellule->NomCli);
  58. printf ("\n Prenom du Client : %s",cellule->PrenomCli);
  59. printf ("\n Mail du Client : %s", cellule->MailCli);
  60. printf ("\n Numero de Telephone du Client : %s", cellule->TelCli);
  61. printf ("\n\n Date de creation : %s\n\n", ctime(&t));
  62. }
  63.  
  64. int mail_valide(int j)
  65. {
  66. int i = 0;
  67. int d = 0;
  68. while(i < strlen(ListeClient[j].MailCli) && d == 0)
  69. {
  70. if(ListeClient[j].MailCli[i] == '@' && i != 0 && i != strlen(ListeClient[j].MailCli)-1)
  71. {
  72. d = 1;
  73. }
  74. else
  75. {
  76. i++;
  77. }
  78. }
  79. return d;
  80. }
  81.  
  82. int telephone_valide(int j)
  83. {
  84. int i = 0;
  85. int d = 0;
  86. if(strlen(ListeClient[j].TelCli) == 14)
  87. {
  88. d = 1;
  89. if(ListeClient[j].TelCli[2] != '.' || ListeClient[j].TelCli[5] != '.' || ListeClient[j].TelCli[8] != '.' || ListeClient[j].TelCli[11] != '.')
  90. {
  91. d = 0;
  92. }
  93. while(i < strlen(ListeClient[j].TelCli) && d == 1)
  94. {
  95. if(ListeClient[j].TelCli[i] <= '0' && ListeClient[j].TelCli[i] >= '9' && ListeClient[j].TelCli[i] != '.')
  96. {
  97. d = 0;
  98. }
  99. else
  100. {
  101. i++;
  102. }
  103. }
  104. }
  105. return d;
  106. }
  107.  
  108. void SaisirClient(int i)
  109. {
  110. char Identifiant[9];
  111.  
  112. FILE *fichier;
  113.  
  114. if ((fichier = fopen("annuaire.txt", "r")) == NULL)
  115. {
  116. printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n");
  117. exit(1);
  118. }
  119.  
  120. system("CLS");
  121. printf (" Saisie du %d ieme Client: \n", i + 1 );
  122.  
  123. printf ("\n Entrez l'identifiant: ");
  124. scanf ("%s", &ListeClient[i].Identifiant);
  125. while(fscanf(fichier,"\n%[^*]*", &Identifiant)!=EOF) // tant que la fin du fichier n'est pas atteint
  126. {
  127. if(strcmp(Identifiant, ListeClient[0].Identifiant)==0)
  128. {
  129. printf ("\n Erreur: l'Identifiant existe deja. Recommencez: ");
  130. scanf ("%s", &ListeClient[i].Identifiant);
  131. }
  132. } // fin du while
  133. fclose(fichier);
  134.  
  135. printf ("\n Entrez le nom de l'entreprise: ");
  136. fflush (stdin);
  137. gets (ListeClient[i].NomEnt);
  138.  
  139. printf ("\n Entrez le numero de rue: ");
  140. scanf ("%s",&ListeClient[i].AdrEnt_Cli.Num);
  141.  
  142. printf ("\n Entrez le nom de la rue: ");
  143. fflush (stdin);
  144. gets (ListeClient[i].AdrEnt_Cli.Rue);
  145.  
  146. printf ("\n Entrez le Code Postal: ");
  147. fflush (stdin);
  148. gets (ListeClient[i].AdrEnt_Cli.CodePostal);
  149.  
  150. printf ("\n Entrez le nom du Client: ");
  151. fflush (stdin);
  152. gets (ListeClient[i].NomCli);
  153.  
  154. printf ("\n Entrez le prenom du Client: ");
  155. fflush (stdin);
  156. gets (ListeClient[i].PrenomCli);
  157.  
  158. printf ("\n Entrez le mail: ");
  159. scanf ("%s",&ListeClient[i].MailCli);
  160. while(mail_valide(i) == 0)
  161. {
  162. printf ("\n Erreur: le mail est incorrect. Recommencez:");
  163. scanf ("%s",&ListeClient[i].MailCli);
  164. }
  165.  
  166. printf ("\n Entrez le numero de Telephone: ");
  167. scanf ("%s",&ListeClient[i].TelCli);
  168. while(telephone_valide(i) == 0)
  169. {
  170. printf ("\n Erreur: telephone incorrect (forme: 00.00.00.00.00). Recommencez:");
  171. scanf ("%s",&ListeClient[i].TelCli);
  172. }
  173.  
  174. AfficheClient(&ListeClient[i]);
  175. system("PAUSE");
  176. }
  177.  
  178.  
  179. void Enregistrement(int NbreClients)
  180. {
  181. char str[8];
  182. char chainefic[1000];
  183. int index;
  184. int k;
  185. int lg,i;
  186. char newline[2]= "\n";
  187.  
  188. time_t t = time(NULL);
  189. srand(time(NULL));
  190. time(&t);
  191.  
  192. FILE *files;
  193.  
  194. // a = mode d'ajout, rajouterez du texte à la fin du fichier
  195. if ((files = fopen("annuaire.txt", "a+t")) == NULL)
  196. {
  197. printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n");
  198. exit(1);
  199. }
  200.  
  201.  
  202. for(i=0; i < NbreClients; i++)
  203. {
  204. index = 0;
  205. k = 0;
  206. // Enregistrement de l'identifiant
  207. lg = strlen(ListeClient[i].Identifiant); //prend la taille de l'identifiant
  208. while (k < lg)
  209. {
  210. chainefic[index++] = ListeClient[i].Identifiant[k++];
  211. }
  212. chainefic[index++] = '*';
  213.  
  214. // Enregistrement du Nom de l'entreprise
  215. k = 0;
  216. lg = strlen(ListeClient[i].NomEnt);
  217. while (k < lg)
  218. {
  219. chainefic[index++] = ListeClient[i].NomEnt[k++];
  220. }
  221. chainefic[index++] = '*';
  222.  
  223. // Enregistrement du numéro de la rue
  224.  
  225. k =0;
  226. lg = strlen(ListeClient[i].AdrEnt_Cli.Num);
  227. while(k < lg)
  228. {
  229. chainefic[index++] = ListeClient[i].AdrEnt_Cli.Num[k++];
  230. }
  231. chainefic[index++] = '*';
  232.  
  233. // Enregistrement de du nom de la rue
  234. k = 0;
  235. lg = strlen(ListeClient[i].AdrEnt_Cli.Rue);
  236. while(k < lg)
  237. {
  238. chainefic[index++] = ListeClient[i].AdrEnt_Cli.Rue[k++];
  239. }
  240. chainefic[index++] = '*';
  241.  
  242. // Enregistrement du code postal
  243. k = 0;
  244. lg = strlen(ListeClient[i].AdrEnt_Cli.CodePostal);
  245. while(k < lg)
  246. {
  247. chainefic[index++] = ListeClient[i].AdrEnt_Cli.CodePostal[k++];
  248. }
  249. chainefic[index++] = '*';
  250.  
  251. // Enregistrement du Nom du Client
  252. k = 0;
  253. lg = strlen(ListeClient[i].NomCli);
  254. while(k < lg)
  255. {
  256. chainefic[index++] = ListeClient[i].NomCli[k++];
  257. }
  258. chainefic[index++] = '*';
  259.  
  260. // Enregistrement du Prénom du Client
  261. k = 0;
  262. lg = strlen(ListeClient[i].PrenomCli);
  263. while(k < lg)
  264. {
  265. chainefic[index++] = ListeClient[i].PrenomCli[k++];
  266. }
  267. chainefic[index++] = '*';
  268.  
  269. // Enregistrement du Mail
  270. k = 0;
  271. lg = strlen(ListeClient[i].MailCli);
  272. while(k < lg)
  273. {
  274. chainefic[index++] = ListeClient[i].MailCli[k++];
  275. }
  276. chainefic[index++] = '*';
  277.  
  278. // Enregistrement du Numéro de Téléphone
  279. k = 0;
  280. lg = strlen(ListeClient[i].TelCli);
  281. while(k < lg)
  282. {
  283. chainefic[index++] = ListeClient[i].TelCli[k++];
  284. }
  285. chainefic[index++] = '*';
  286.  
  287. // Enregistrement de la date de creation
  288. k = 0;
  289. lg = strlen(ctime(&t));
  290. while(k < (lg-1))
  291. {
  292. chainefic[index++] = ctime(&t)[k++];
  293. }
  294. chainefic[index++] = '*';
  295. chainefic[index++] = '\0';
  296.  
  297. // Ecrire le resultat dans le fichier et revenir à la ligne !!
  298. fprintf(files,newline);
  299. fputs(chainefic,files);
  300. }
  301. fclose(files);
  302. }
  303.  
  304.  
  305. int main()
  306. {
  307. int continuer;
  308. int NbreClients;
  309. int c,i;
  310. int Sortie = FAUX;
  311.  
  312. while(!Sortie)
  313. {
  314.  
  315. system("CLS");
  316. printf("\n\t****************************************\n");
  317. printf("\n\t\tGestion de l'annuaire Clients\n");
  318. printf("\n\t****************************************\n");
  319.  
  320. printf("\n\t\tA : Ajouter");
  321. printf("\n\t\tR : Rechercher");
  322. printf("\n\t\tM : Modifier");
  323. printf("\n\t\tS : Supprimer");
  324. printf("\n\t\tL : Lister");
  325. printf("\n\t\tQ : Quitter\n");
  326. printf("\n\t****************************************\n");
  327. printf("\n\t\tChoix <A, R, M, S, L, Q> : ");
  328.  
  329. c = getchar();
  330. switch(c)
  331. {
  332. case 'a':
  333. case 'A':
  334. system("CLS");
  335. printf (" Fonction ajouter: \n");
  336.  
  337. printf("\n Combien de clients voulez-vous ajouter? ");
  338. scanf("%d", &NbreClients);
  339.  
  340.  
  341. for (i = 0; i < NbreClients; i++)
  342. {
  343. SaisirClient(i);
  344. }
  345.  
  346. Enregistrement(NbreClients);
  347.  
  348. break; // CASE1
  349.  
  350. case 'r':
  351. case 'R':
  352. system("CLS");
  353. printf(" Fonction Rechercher: \n");
  354. if (Rechercher() == 0)
  355. {
  356. AfficheClient(&ListeClient[0]);
  357. }
  358. else
  359. {
  360. printf("Erreur de recherche : la fiche du client n'existe pas ou erreur de saisie");
  361. }
  362. printf("\n\n");
  363. system("PAUSE");
  364. break; // CASE2
  365.  
  366. case 'm':
  367. case 'M':
  368. system("CLS");
  369. printf(" Fonction Modifier: \n");
  370. if (Rechercher() == 0)
  371. {
  372. Modifier(&ListeClient[0]);
  373. }
  374. else
  375. {
  376. printf("Erreur de recherche : la fiche du client n'existe pas ou erreur de saisie");
  377. }
  378. printf("\n\n");
  379. system("PAUSE");
  380. break; // CASE3
  381.  
  382. case 's':
  383. case 'S':
  384. system("CLS");
  385. printf(" Fonction Supprimer: \n");
  386. Supprimer();
  387. printf("\n\n");
  388. system("PAUSE");
  389. break; // CASE5
  390.  
  391. case 'l':
  392. case 'L':
  393. system("CLS");
  394. printf(" Fonction Lister: \n");
  395. Lister();
  396. printf("\n\n");
  397. system("PAUSE");
  398. break; // CASE6
  399.  
  400. case 'q':
  401. case 'Q':
  402. Sortie = FAUX;
  403. continuer = VRAI;
  404. system("CLS");
  405. printf(" FIN APPLICATION\n");
  406. printf("\n Quitter l'Application <O,N>? ");
  407. while(continuer)
  408. {
  409. c = getchar ();
  410. switch(c)
  411. {
  412. case 'o':
  413. case 'O':
  414. continuer = FAUX;
  415. Sortie = VRAI;
  416. break;
  417.  
  418. case 'n':
  419. case 'N':
  420. continuer = FAUX;
  421. break;
  422. }
  423. }
  424. break;
  425.  
  426. default :
  427. break;
  428. }
  429.  
  430. if(Sortie)
  431. {
  432. break;
  433. }
  434. }
  435. return 0;
  436. }
12 Avril 2008 10:15:35

J'ai fait comme ma conseillé Cart de mettre des printf (j'ai saisie comme valeur pour NbreClient = 2 pour qu'il fasse la boucle deux fois), j'en ai mis un avant le for (il met la bonne valeur: 2), un dans le for avant l'appelle de la fonction SaisieClient, premier tour c bon il m'affiche 2, met le 2eme tour, il m'affiche 2293560. Donc le problème doit venir de la boucle enfin je sais pas, je comprend vraiment pas ce qui se passe!!
Anonyme
12 Avril 2008 12:29:18

en effet c'est assez long, pour situer mieux le problème, affiches nbreClient après chaque while qui sont dans le for, numérotes les printf pour pouvoir les discerner
12 Avril 2008 14:40:47

Ok je vais essayé, et merci encore de m'aider
12 Avril 2008 15:38:44

J'ai essayé mais le problème vient d'avant la fonction enregistrer car NbreClients =2293560 avant la fonction enregistrer, mais le problème c'est que je n'utilise pas NbreClient dans les fonction d'avant donc normalement sa devrai pas changer!!
12 Avril 2008 15:43:58

J'ai l'impression que sa vient du code suivant ce trouvant dans le début de la Fonction SaisieClient:

  1. while(fscanf(fichier,"\n%[^*]*", &Identifiant)!=EOF) // tant que la fin du fichier n'est pas atteint
  2. {
  3. if(strcmp(Identifiant, ListeClient[i].Identifiant)==0)
  4. {
  5. printf ("\n Erreur: l'Identifiant existe deja. Recommencez: ");
  6. scanf ("%s", &ListeClient[i].Identifiant);
  7. }
  8. } // fin du while


En effet, quand je met ce bout de code en commentaire, sa fonctionne!!
Mais je vois pas en quoi sa modifierai NbreClients.
a b L Programmation
13 Avril 2008 17:10:45

seb326 a dit :
J'ai essayé mais le problème vient d'avant la fonction enregistrer car NbreClients =2293560 avant la fonction enregistrer, mais le problème c'est que je n'utilise pas NbreClient dans les fonction d'avant donc normalement sa devrai pas changer!!

C'est possible. En mémoire, les variables sont placées les unes après les autres. Si tu es sur une variable et que tu dépasses la taille, tu vas écrire sur une autre variable (sans savoir laquelle). C'est ce qui s'appelle le "buffer overflow".

Dans ton code, je vois que DIM_LISTE n'est utilisé que 2 fois : dans le #define et l'initialisation du tableau. ça veut donc dire, que tu ne fait aucun contrôle de dépassement de taille. Tu dois toujours faire des contrôles lorsque tu ajoutes quelque chose que ce soit un nouvel élément ou une chaine, pour justement éviter les buffers overflow.

Lorsque, comme je te l'avais suggéré, tu auras mis tous ces contrôles, tu remettras ton code, et je le lirai.
Ton programme n'est pas très complexe. Je pense, qu'en y ajoutant tous les contrôles, tu trouveras facilement le problème.
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS