Problème écriture dans un fichier en language C
Dernière réponse : dans Programmation
Bonjours à tous,
dans le main(), sa ce présente comme ça:
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
void SaisirClient(int i) { char Identifiant[9]; FILE *fichier; if ((fichier = fopen("annuaire.txt", "r")) == NULL) { printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n"); exit(1); } system("CLS"); printf (" Saisie du %d ieme Client: \n", i + 1 ); printf ("\n Entrez l'identifiant: "); scanf ("%s", &ListeClient[i].Identifiant); while(fscanf(fichier,"\n%[^*]*", &Identifiant)!=EOF) // tant que la fin du fichier n'est pas atteint { if(strcmp(Identifiant, ListeClient[0].Identifiant)==0) { printf ("\n Erreur: l'Identifiant existe deja. Recommencez: "); scanf ("%s", &ListeClient[i].Identifiant); } } // fin du while fclose(fichier); }
void Enregistrement(int NbreClients) { char str[8]; char chainefic[1000]; int index; int k; int lg,i; char newline[2]= "\n"; FILE *files; if ((files = fopen("annuaire.txt", "a")) == NULL) { printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n"); exit(1); } for(i=0; i < NbreClients; i++) { //instruction longue donc je vous la met pas } fclose(files); }
dans le main(), sa ce présente comme ça:
for (i = 0; i < NbreClients; i++) { SaisirClient(i); } 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
Lassé par la pub ? Créez un compte
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.
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.
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.
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.
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.
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.
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.
(fonctions retiré: Lister(), Modifier(Client *cellule), Supprimer(), Rechercher())
Merci d'avance pour ceux qui essayeront de comprendre mon code.
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#define DIM_ID 9
#define DIM_LISTE 5
#define DIM_CHAINE 40
#define DIM_NUMTEL 15
#define DIM_CP 6 //6 pas 5 car \o fin de chaine de caractere
#define DIM_NUM 7 // car il peut y avoir des bis,ter...
#define DIM_DATE 30
#define VRAI 1
#define FAUX 0
#define LGMAX 1000
#define TAILLE_MAX 1000
// Definition de la structure nommée Adresse
typedef struct Adresse
{
char Num[DIM_NUM];
char Rue[DIM_CHAINE];
char CodePostal[DIM_CP] ;
}Adresse ;
// Definition de la structure nommée Client
typedef struct Client
{
char Identifiant[DIM_ID];
char NomEnt[DIM_CHAINE];
struct Adresse AdrEnt_Cli;
char NomCli[DIM_CHAINE];
char PrenomCli[DIM_CHAINE];
char MailCli[DIM_CHAINE];
char TelCli[DIM_NUMTEL];
char Date[DIM_DATE];
}Client ;
Client ListeClient[DIM_LISTE];
Adresse LireAdresse ();
void AfficheClient(Client *cellule)
{
time_t t = time(NULL);
srand( time(NULL) );
time(&t);
printf ("\n Identifiant : %s", cellule->Identifiant);
printf ("\n Nom de l'entreprise : %s", cellule->NomEnt);
printf ("\n Adresse : %s, %s %s", cellule->AdrEnt_Cli.Num,cellule->AdrEnt_Cli.Rue,cellule->AdrEnt_Cli.CodePostal);
printf ("\n Nom du Client : %s", cellule->NomCli);
printf ("\n Prenom du Client : %s",cellule->PrenomCli);
printf ("\n Mail du Client : %s", cellule->MailCli);
printf ("\n Numero de Telephone du Client : %s", cellule->TelCli);
printf ("\n\n Date de creation : %s\n\n", ctime(&t));
}
int mail_valide(int j)
{
int i = 0;
int d = 0;
while(i < strlen(ListeClient[j].MailCli) && d == 0)
{
if(ListeClient[j].MailCli[i] == '@' && i != 0 && i != strlen(ListeClient[j].MailCli)-1)
{
d = 1;
}
else
{
i++;
}
}
return d;
}
int telephone_valide(int j)
{
int i = 0;
int d = 0;
if(strlen(ListeClient[j].TelCli) == 14)
{
d = 1;
if(ListeClient[j].TelCli[2] != '.' || ListeClient[j].TelCli[5] != '.' || ListeClient[j].TelCli[8] != '.' || ListeClient[j].TelCli[11] != '.')
{
d = 0;
}
while(i < strlen(ListeClient[j].TelCli) && d == 1)
{
if(ListeClient[j].TelCli[i] <= '0' && ListeClient[j].TelCli[i] >= '9' && ListeClient[j].TelCli[i] != '.')
{
d = 0;
}
else
{
i++;
}
}
}
return d;
}
void SaisirClient(int i)
{
char Identifiant[9];
FILE *fichier;
if ((fichier = fopen("annuaire.txt", "r")) == NULL)
{
printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n");
exit(1);
}
system("CLS");
printf (" Saisie du %d ieme Client: \n", i + 1 );
printf ("\n Entrez l'identifiant: ");
scanf ("%s", &ListeClient[i].Identifiant);
while(fscanf(fichier,"\n%[^*]*", &Identifiant)!=EOF) // tant que la fin du fichier n'est pas atteint
{
if(strcmp(Identifiant, ListeClient[0].Identifiant)==0)
{
printf ("\n Erreur: l'Identifiant existe deja. Recommencez: ");
scanf ("%s", &ListeClient[i].Identifiant);
}
} // fin du while
fclose(fichier);
printf ("\n Entrez le nom de l'entreprise: ");
fflush (stdin);
gets (ListeClient[i].NomEnt);
printf ("\n Entrez le numero de rue: ");
scanf ("%s",&ListeClient[i].AdrEnt_Cli.Num);
printf ("\n Entrez le nom de la rue: ");
fflush (stdin);
gets (ListeClient[i].AdrEnt_Cli.Rue);
printf ("\n Entrez le Code Postal: ");
fflush (stdin);
gets (ListeClient[i].AdrEnt_Cli.CodePostal);
printf ("\n Entrez le nom du Client: ");
fflush (stdin);
gets (ListeClient[i].NomCli);
printf ("\n Entrez le prenom du Client: ");
fflush (stdin);
gets (ListeClient[i].PrenomCli);
printf ("\n Entrez le mail: ");
scanf ("%s",&ListeClient[i].MailCli);
while(mail_valide(i) == 0)
{
printf ("\n Erreur: le mail est incorrect. Recommencez:");
scanf ("%s",&ListeClient[i].MailCli);
}
printf ("\n Entrez le numero de Telephone: ");
scanf ("%s",&ListeClient[i].TelCli);
while(telephone_valide(i) == 0)
{
printf ("\n Erreur: telephone incorrect (forme: 00.00.00.00.00). Recommencez:");
scanf ("%s",&ListeClient[i].TelCli);
}
AfficheClient(&ListeClient[i]);
system("PAUSE");
}
void Enregistrement(int NbreClients)
{
char str[8];
char chainefic[1000];
int index;
int k;
int lg,i;
char newline[2]= "\n";
time_t t = time(NULL);
srand(time(NULL));
time(&t);
FILE *files;
// a = mode d'ajout, rajouterez du texte à la fin du fichier
if ((files = fopen("annuaire.txt", "a+t")) == NULL)
{
printf ("\n Impossible d'ouvrir le fichier annuaire.txt \n");
exit(1);
}
for(i=0; i < NbreClients; i++)
{
index = 0;
k = 0;
// Enregistrement de l'identifiant
lg = strlen(ListeClient[i].Identifiant); //prend la taille de l'identifiant
while (k < lg)
{
chainefic[index++] = ListeClient[i].Identifiant[k++];
}
chainefic[index++] = '*';
// Enregistrement du Nom de l'entreprise
k = 0;
lg = strlen(ListeClient[i].NomEnt);
while (k < lg)
{
chainefic[index++] = ListeClient[i].NomEnt[k++];
}
chainefic[index++] = '*';
// Enregistrement du numéro de la rue
k =0;
lg = strlen(ListeClient[i].AdrEnt_Cli.Num);
while(k < lg)
{
chainefic[index++] = ListeClient[i].AdrEnt_Cli.Num[k++];
}
chainefic[index++] = '*';
// Enregistrement de du nom de la rue
k = 0;
lg = strlen(ListeClient[i].AdrEnt_Cli.Rue);
while(k < lg)
{
chainefic[index++] = ListeClient[i].AdrEnt_Cli.Rue[k++];
}
chainefic[index++] = '*';
// Enregistrement du code postal
k = 0;
lg = strlen(ListeClient[i].AdrEnt_Cli.CodePostal);
while(k < lg)
{
chainefic[index++] = ListeClient[i].AdrEnt_Cli.CodePostal[k++];
}
chainefic[index++] = '*';
// Enregistrement du Nom du Client
k = 0;
lg = strlen(ListeClient[i].NomCli);
while(k < lg)
{
chainefic[index++] = ListeClient[i].NomCli[k++];
}
chainefic[index++] = '*';
// Enregistrement du Prénom du Client
k = 0;
lg = strlen(ListeClient[i].PrenomCli);
while(k < lg)
{
chainefic[index++] = ListeClient[i].PrenomCli[k++];
}
chainefic[index++] = '*';
// Enregistrement du Mail
k = 0;
lg = strlen(ListeClient[i].MailCli);
while(k < lg)
{
chainefic[index++] = ListeClient[i].MailCli[k++];
}
chainefic[index++] = '*';
// Enregistrement du Numéro de Téléphone
k = 0;
lg = strlen(ListeClient[i].TelCli);
while(k < lg)
{
chainefic[index++] = ListeClient[i].TelCli[k++];
}
chainefic[index++] = '*';
// Enregistrement de la date de creation
k = 0;
lg = strlen(ctime(&t));
while(k < (lg-1))
{
chainefic[index++] = ctime(&t)[k++];
}
chainefic[index++] = '*';
chainefic[index++] = '\0';
// Ecrire le resultat dans le fichier et revenir à la ligne !!
fprintf(files,newline);
fputs(chainefic,files);
}
fclose(files);
}
int main()
{
int continuer;
int NbreClients;
int c,i;
int Sortie = FAUX;
while(!Sortie)
{
system("CLS");
printf("\n\t****************************************\n");
printf("\n\t\tGestion de l'annuaire Clients\n");
printf("\n\t****************************************\n");
printf("\n\t\tA : Ajouter");
printf("\n\t\tR : Rechercher");
printf("\n\t\tM : Modifier");
printf("\n\t\tS : Supprimer");
printf("\n\t\tL : Lister");
printf("\n\t\tQ : Quitter\n");
printf("\n\t****************************************\n");
printf("\n\t\tChoix <A, R, M, S, L, Q> : ");
c = getchar();
switch(c)
{
case 'a':
case 'A':
system("CLS");
printf (" Fonction ajouter: \n");
printf("\n Combien de clients voulez-vous ajouter? ");
scanf("%d", &NbreClients);
for (i = 0; i < NbreClients; i++)
{
SaisirClient(i);
}
Enregistrement(NbreClients);
break; // CASE1
case 'r':
case 'R':
system("CLS");
printf(" Fonction Rechercher: \n");
if (Rechercher() == 0)
{
AfficheClient(&ListeClient[0]);
}
else
{
printf("Erreur de recherche : la fiche du client n'existe pas ou erreur de saisie");
}
printf("\n\n");
system("PAUSE");
break; // CASE2
case 'm':
case 'M':
system("CLS");
printf(" Fonction Modifier: \n");
if (Rechercher() == 0)
{
Modifier(&ListeClient[0]);
}
else
{
printf("Erreur de recherche : la fiche du client n'existe pas ou erreur de saisie");
}
printf("\n\n");
system("PAUSE");
break; // CASE3
case 's':
case 'S':
system("CLS");
printf(" Fonction Supprimer: \n");
Supprimer();
printf("\n\n");
system("PAUSE");
break; // CASE5
case 'l':
case 'L':
system("CLS");
printf(" Fonction Lister: \n");
Lister();
printf("\n\n");
system("PAUSE");
break; // CASE6
case 'q':
case 'Q':
Sortie = FAUX;
continuer = VRAI;
system("CLS");
printf(" FIN APPLICATION\n");
printf("\n Quitter l'Application <O,N>? ");
while(continuer)
{
c = getchar ();
switch(c)
{
case 'o':
case 'O':
continuer = FAUX;
Sortie = VRAI;
break;
case 'n':
case 'N':
continuer = FAUX;
break;
}
}
break;
default :
break;
}
if(Sortie)
{
break;
}
}
return 0;
}
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!!
J'ai l'impression que sa vient du code suivant ce trouvant dans le début de la Fonction SaisieClient:
En effet, quand je met ce bout de code en commentaire, sa fonctionne!!
Mais je vois pas en quoi sa modifierai NbreClients.
while(fscanf(fichier,"\n%[^*]*", &Identifiant)!=EOF) // tant que la fin du fichier n'est pas atteint
{
if(strcmp(Identifiant, ListeClient[i].Identifiant)==0)
{
printf ("\n Erreur: l'Identifiant existe deja. Recommencez: ");
scanf ("%s", &ListeClient[i].Identifiant);
}
} // 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.
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.
Lassé par la pub ? Créez un compte