Fichier en C :(
Résolu
didy_gwatinik
Messages postés
352
Date d'inscription
Statut
Membre
Dernière intervention
-
didy_gwatinik Messages postés 352 Date d'inscription Statut Membre Dernière intervention -
didy_gwatinik Messages postés 352 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
Est-ce quelqu'un peut m'aider, je suis à bout. Voila : c'est un programme pour créer un répertoire, tout va bien lorsque l'on ouvre le programme pour la 1ère fois mais lorsqu'on ferme le programme, il y a copie du contenu des variables dans un fichier puis lors de la réouverture du programme il y a copie de ce que contient le fichier dans les variables. C'est ici que se pose le problème, je dois avoir un problème avec mes variables parce que ça met que le fichier ne contient aucun contact alors que la première ligne du fichier (qui indique le nombre de contact) contient 1. Je ne sais pas si je suis assez claire! Je vous poste aussi mon code :
Est-ce quelqu'un peut m'aider, je suis à bout. Voila : c'est un programme pour créer un répertoire, tout va bien lorsque l'on ouvre le programme pour la 1ère fois mais lorsqu'on ferme le programme, il y a copie du contenu des variables dans un fichier puis lors de la réouverture du programme il y a copie de ce que contient le fichier dans les variables. C'est ici que se pose le problème, je dois avoir un problème avec mes variables parce que ça met que le fichier ne contient aucun contact alors que la première ligne du fichier (qui indique le nombre de contact) contient 1. Je ne sais pas si je suis assez claire! Je vous poste aussi mon code :
#include<stdio.h> #include<conio.h> #include<string.h> #include<stdlib.h> #define N 10 #define taille 52 #define chemin "C:\\repertoire.txt" //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Déclaration de la structure carnet //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ struct carnet { char nom[20]; char prenom[20]; char numTel[11]; char mel[50]; char motdepasse[9]; }tab[N]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Procedure Presentation //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void presentation() { printf("\n\n\n\n\n\n"); puts(" *****************************************************"); puts(" * *"); puts(" * CARNET D'ADRESSE *"); puts(" * *"); puts(" *****************************************************"); printf("\n\n\n\n\n\n"); system("pause"); system("cls"); } //+++++++++++++++++++++++++++++++++++++++++++++++ //Procedure NomPresent //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void nomPresent(int *nbContact) { int i=0; puts("Voici les contacts presents dans votre repertoire"); for(i=0;i<*nbContact;i++) { printf("%s\n", tab[i].nom); } } //++++++++++++++++++++++++++ //Procedure decryptageFichier //+++++++++++++++++++++++++ void decryptageFichier(int *nbContact) { int i=0; char nomSaisi[20],motdepasse[9]; system("cls"); nomPresent(nbContact); puts("De quelle personne voulez vous decrypter l'acces aux coordonnes ?"); scanf("%s", &nomSaisi); for(i=0;i<*nbContact;i++) { if(strcmp(nomSaisi,tab[i].nom)==0) break; } if(strlen(tab[i].motdepasse)>1) { printf("Mot de passe : "); scanf("%s",&motdepasse); if(strcmp(motdepasse,tab[i].motdepasse)==0) printf("L'acces aux coordonnees a ete decrypte"); strcpy(tab[i].motdepasse,0); //le mot de passe ne contient plus de caractere } else{printf("Il n'y a pas de mot de passe pour cette personne");} getch(); } //++++++++++++++++++++++++++++++++++++++++++ //Procedure SuppressionFiche //++++++++++++++++++++++++++++++++++++++++ void suppressionFiche(int *nbContact) { int i=0,reponse=0; char nomSaisi[20]; system("cls"); nomPresent(nbContact); puts("De quelle personne voulez-vous supprimer la fiche?"); scanf("%s", &nomSaisi); for(i=0;i<*nbContact;i++) { if(strcmp(nomSaisi,tab[i].nom)==0) break; } printf("Validez la suppression des coordonnées de %s %s en tapant sur 1\n", tab[i].nom, tab[i].prenom); scanf("%d", &reponse); if(reponse==1) { //copie du contenu de la derniere fiche a la place de celle a supprimer strcpy(tab[i].nom,tab[*nbContact].nom); strcpy(tab[i].prenom,tab[*nbContact].prenom); strcpy(tab[i].numTel,tab[*nbContact].numTel); strcpy(tab[i].mel,tab[*nbContact].mel); //on enleve un contact *nbContact--; printf("Les donnees ont ete supprimees"); } getch(); } //+++++++++++++++++++++++++ //Fonction Verification adresse mail //+++++++++++++++++++++++++++ int verifMel(char *mel) { int i=0,correct=0; for(i=0;i<(strlen(mel));i++) { if(mel[i]=='@') { if(mel[(strlen(mel)-3)]=='.')//accès au 3eme caractere en partant de la fin de l'adresse mail { correct=1; } } } return correct; } //++++++++++++++++++++++++++++ //Fonction Creation Fiche //++++++++++++++++++++++++++++ void creationFiche(int *nbContact) { int static i=0, correct=0; system("cls"); puts("Creation Fiche Contact"); puts("Nom : "); scanf("%s", &tab[i].nom); puts("Prenom : "); scanf("%s", &tab[i].prenom); do { puts("Numero de telephone : "); scanf("%s", &tab[i].numTel); }while(strlen(tab[i].numTel)!=10); //test si le nombre de chiffre saisie est de 10 à l'aide de la longueur de la chaine do { puts("Adresse mail : "); scanf("%s", &tab[i].mel); correct=verifMel(tab[i].mel); }while(correct!=1); *tab[i].motdepasse=0; printf("Les informations concernant %s %s ont ete enregistrees", tab[i].nom, tab[i].prenom); i=i+1; *nbContact=i; getch(); } //++++++++++++++++++++++++++++++++++++++++++ //Procedure Consultation Fiche //++++++++++++++++++++++++++++++++++++++ void consulterFiche(int *nbContact) { int i=0,ecriture=0; char choix[20],motdepasse[9]; system("cls"); nomPresent(nbContact); puts("Veuillez saisir le nom de la personne dont vous souhaitez lire la fiche"); scanf("%s", &choix); for(i=0;i<*nbContact;i++) { if(strcmp(tab[i].nom,choix)==0) { if(strlen(tab[i].motdepasse)>1) { printf("Mot de passe : "); fflush(stdin); gets(motdepasse); if(strcmp(motdepasse,tab[i].motdepasse)==0) { printf("%s\n%s\n%s\n%s\n", tab[i].nom, tab[i].prenom, tab[i].numTel, tab[i].mel); ecriture=1; } } else{ printf("%s\n%s\n%s\n%s\n", tab[i].nom, tab[i].prenom, tab[i].numTel, tab[i].mel); ecriture=1; } } } if(ecriture!=1) puts("Erreur de saisie"); getch(); } //++++++++++++++++++++++ //Procedure cryptageFiche //++++++++++++++++++++++++ void cryptageFiche(int *nbContact) { int i=0; char motdepasse1[9],nomSaisi[20]; system("cls"); nomPresent(nbContact); puts("De quelle personne voulez vous crypter les coordonnees"); scanf("%s", &nomSaisi); for(i=0;i<*nbContact;i++) { if(strcmp(nomSaisi,tab[i].nom)==0) break; } do { puts("Veuillez entrer un mot de passe maximum 8 caracteres"); fflush(stdin); scanf("%s",&motdepasse1); puts("Confirmer mot de passe : "); fflush(stdin); scanf("%s",&tab[i].motdepasse); }while(strcmp(motdepasse1,tab[i].motdepasse)!=0); printf("Le mot de passe est confirme pour l'acces aux coordonnees de %s %s", tab[i].nom, tab[i].prenom); getch(); } //+++++++++++++++++++++++++ //Procedure ModificationFiche //+++++++++++++++++++++++ void modificationFiche(int *nbContact) { int i=0,correct=0; char nomSaisi[20]; system("cls"); nomPresent(nbContact); puts("De quelle personne souhaitez vous modifier les coordonnees ?"); scanf("%s", &nomSaisi); //Recherche de l'indice du nom for(i=0;i<*nbContact;i++) { if(strcmp(nomSaisi,tab[i].nom)==0) break; } if(i<*nbContact)//Le nom a été trouvé { printf("Veuillez saisir les nouvelles informations concernant %s %s\n", tab[i].nom, tab[i].prenom); puts("Nom : "); scanf("%s", &tab[i].nom); puts("Prenom : "); scanf("%s", &tab[i].prenom); do { puts("Numero de telephone : "); scanf("%s", &tab[i].numTel); }while(strlen(tab[i].numTel)!=10); //test si le nombre de chiffre saisie est de 10 à l'aide de la longueur de la chaine do { puts("Adresse mail : "); scanf("%s", &tab[i].mel); correct=verifMel(tab[i].mel); }while(correct!=1); printf("Les informations concernant %s %s ont ete modifiees", tab[i].nom, tab[i].prenom); } else{printf("Le nom trouve n'apparait pas dans la liste de vos contacts");} getch(); } //+++++++++++++++++++++++++++++ //Procedure Suppression //+++++++++++++++++++++++++++++ void suppressionCarnet(int *nbContact) { int reponse=0; system("cls"); puts("Appuyez sur 1 pour confirmer la supression du carnet"); scanf("%d", &reponse); if(reponse==1) { *nbContact=0; puts("Les donnees ont ete effacees"); } getch(); } //+++++++++++++++++++++++++++++++++++ //Proocedur Enregistrement //++++++++++++++++++++++++++++++++++++++++++ void enregistrement(int *nbContact) { FILE *fichier = NULL; int i=0; fichier=fopen(chemin,"w"); //w pour ecraser l'ancien enregistrement if (fichier != NULL) { fprintf(fichier,"%d",*nbContact); fprintf(fichier,"\n"); for(i=0;i<*nbContact;i++) { fprintf(fichier,tab[i].nom); fprintf(fichier,"\n"); fprintf(fichier,tab[i].prenom); fprintf(fichier,"\n"); fprintf(fichier,tab[i].numTel); fprintf(fichier,"\n"); fprintf(fichier,tab[i].mel); fprintf(fichier,"\n"); fprintf(fichier,tab[i].motdepasse); fprintf(fichier,"\n"); } } fclose(fichier); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Procedure fichier Variable qui copie le contenu des fichiers dans des variables //++++++++++++++++++++++++++++++++++++++++++++++++++++ void fichierVariable(int *nbContact) { FILE *fichier = NULL; //initialisation du pointeur de fichier char chaine[taille]; int i=0,j=0; fichier=fopen(chemin,"r");//lecture seule if(fichier!=NULL) { while(!feof(fichier)) { fflush(stdin); fgets(chaine,taille,fichier); *nbContact=atoi(chaine); // for(j=0;j<*nbContact;j++) // { for(i=0;i<*nbContact;i++)//4 car il y a 5 champs ds la structure { fflush(stdin); fgets(chaine,taille,fichier); strcpy(tab[i].nom,chaine); fflush(stdin); fgets(chaine,taille,fichier); strcpy(tab[i].prenom,chaine); fflush(stdin); fgets(chaine,taille,fichier); strcpy(tab[i].numTel,chaine); fflush(stdin); fgets(chaine,taille,fichier); strcpy(tab[i].mel,chaine); fflush(stdin); fgets(chaine,taille,fichier); strcpy(tab[i].motdepasse,chaine); } //} } } fclose(fichier); } //++++++++++++++++++++++++++ //Procedure Menu //++++++++++++++++++++++++++ void menu() { int choix=0,nbContact=0; fichierVariable(&nbContact); do{ system("cls"); puts("Que voulez vous faire?\n\n\t1 : Creer une fiche contact\n\t2 : Consulter une fiche\n\t3 : Ajouter et mettre a jour une fiche\n\t4 : Modifier une fiche\n\t5 : Supprimer une fiche\n\t6 : Supprimer votre carnet d'adresse\n\t7 : Afficher le nombre de vos contacts\n\t8 : Crypter un fichier\n\t9 : Decrypter un fichier\n\t10 : Quitter\n"); scanf("%d", &choix); //on ne teste pas car la condition est testée avec le default du switch switch(choix) { case 1 : { creationFiche(&nbContact); } break; case 2 : { consulterFiche(&nbContact); } break; case 3 : { ; } break; case 4 : { modificationFiche(&nbContact); } break; case 5 : { suppressionFiche(&nbContact); } break; case 6 : { suppressionCarnet(&nbContact); } break; case 7 : { printf("Il y a %d contacts dans votre repertoire", nbContact); getch(); } break; case 8 : { cryptageFiche(&nbContact); } break; case 9 : { decryptageFichier(&nbContact); } break; case 10 : ; break; default : ; } }while(choix!=10); if(&nbContact>0) enregistrement(&nbContact); } //++++++++++++++++++++++++++ //Programme principal //++++++++++++++++++++++++++ main(void) { presentation(); menu(); getch(); return 0; }
A voir également:
- Fichier en C :(
- Fichier bin - Guide
- Fichier epub - Guide
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier .dat - Guide
12 réponses
Bonjour,
J'essaie de voir ça, (En tout le programme est propre) mais il plante au premier lancer sans créer de fichier.
C'est dans la fonction fichierVariable, il veut ouvrir un fichier qui n'existe pas, cela échoue, le problème est qu'il ferme le fichier qui n'est pas ouvert. Blaf!
Je déplace la ligne et je continue...
M.
J'essaie de voir ça, (En tout le programme est propre) mais il plante au premier lancer sans créer de fichier.
C'est dans la fonction fichierVariable, il veut ouvrir un fichier qui n'existe pas, cela échoue, le problème est qu'il ferme le fichier qui n'est pas ouvert. Blaf!
Je déplace la ligne et je continue...
M.
Au bas du switch:
if( &nbContact > 0 )
:-/
J'ai réussi à rentrer un email ! Je voulais un .com ^^
aze@truc.f@rez.fr est valide. (je pense)
Ca vient, j'ai créé un fichier.
M.
if( &nbContact > 0 )
:-/
J'ai réussi à rentrer un email ! Je voulais un .com ^^
aze@truc.f@rez.fr est valide. (je pense)
Ca vient, j'ai créé un fichier.
M.
Dans fichierVariable:
Pourquoi ne faut-il pas utiliser fflush(stdin) pour vider le buffer clavier ?.
D'autre part, que vient faire l'entrée standard dans la lecture d'un fichier ?
L'erreur à proprement dite:
Ouverture du fichier.
Lecture du nombre de contacts. (J'aurais mis un 's' à nbContact ^^)
Lecture fort peu élégante d'un contact. (1 seul contact dans le fichier)
Le fichier n'est pas vide, nouveau tour de boucle.
Ecrasement du nombre de contacts avec 0.
Passage de la boucle for car i = 0 n'est pas < nbContact = 0.
Le fichier est vide.
fermeture du fichier.
fin de la fonction.
Le contact est chargé correctement malgré les \n qui ont été lu au bout de chaque champ. nbContact vaut zéro.
Remarques autres:
- Idem pour le fclose de l'autre fonction.
- Je conseillerais l'utilisation d'un fichier binaire.
- Le code est propre et lisible. Ca fait plaisir.
M.
Pourquoi ne faut-il pas utiliser fflush(stdin) pour vider le buffer clavier ?.
D'autre part, que vient faire l'entrée standard dans la lecture d'un fichier ?
L'erreur à proprement dite:
Ouverture du fichier.
Lecture du nombre de contacts. (J'aurais mis un 's' à nbContact ^^)
Lecture fort peu élégante d'un contact. (1 seul contact dans le fichier)
Le fichier n'est pas vide, nouveau tour de boucle.
Ecrasement du nombre de contacts avec 0.
Passage de la boucle for car i = 0 n'est pas < nbContact = 0.
Le fichier est vide.
fermeture du fichier.
fin de la fonction.
Le contact est chargé correctement malgré les \n qui ont été lu au bout de chaque champ. nbContact vaut zéro.
Remarques autres:
- Idem pour le fclose de l'autre fonction.
- Je conseillerais l'utilisation d'un fichier binaire.
- Le code est propre et lisible. Ca fait plaisir.
M.
On peut, une fonction inline si possible voire une macro...
Encore avant les scanf l'erreur est tellement commune et les compilateur les plus utilisés supportent ce comportement. Cela pourrait passer. Par contre vider le buffer du clavier en pleine lecture dans un fichier ça choque un tantinet. ^^
M.
Encore avant les scanf l'erreur est tellement commune et les compilateur les plus utilisés supportent ce comportement. Cela pourrait passer. Par contre vider le buffer du clavier en pleine lecture dans un fichier ça choque un tantinet. ^^
M.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
J'aurais fait plus court...
En fait j'aurais fait en utilisant un fichier binaire mais je l'ai déjà dit au dessus et ce n'est pas à moi qu'appartient la décision.
M.
for(i=0;i<*nbContact;i++)//4 car il y a 5 champs ds la structure { fgets(tab[i].nom, sizeof( tab[i].nom ), fichier ); fgets(tab[i].prenom, sizeof( tab[i].prenom ), fichier ); fgets(tab[i].numTel, sizeof( tab[i].numTel ), fichier ); fgets(tab[i].mel, sizeof( tab[i].mel ), fichier ); fgets(tab[i].motdepasse, sizeof( tab[i].motdepasse ), fichier ); }
En fait j'aurais fait en utilisant un fichier binaire mais je l'ai déjà dit au dessus et ce n'est pas à moi qu'appartient la décision.
M.
Petite modification, je déclare le type puis la variable.
typedef struct contact_t
{
char nom[20];
char prenom[20];
char numTel[11];
char mel[50];
char motdepasse[9];
} contact_t;
contact_t tab[N];
Pour le fichier:
fopen( "leFichier.truc", "wb" ); et fopen( "leFichier.truc", "rb" );
fwrite( tab + i, sizeof( contact_t ), 1, fichier );
fread( tab + i, sizeof( contact_t, 1, fichier );
Inconvénient: le fichier est plus gros car les 110 octets maximums de la structure sont toujours écrits; Le fichier ne peut pas être éditer dans un blocnote ou autre.
Avantage: plus simple, plus sûr, plus opaque (il faut un éditeur héxa), on peut envisager de ne lire que le contact 7 sans parcourir tout le fichier.
Comme les contacts sont dans un tableau on peut aussi faire sauter la boucle for:
La fonction de lecture a à peu près la même tête avec un "rb" et des fread.
On peut vérifier le nombre d'objets lus avec succès grace à la valeur de retour pour éventuellement corriger le nbContacts en cas de problème du fichier.
M.
typedef struct contact_t
{
char nom[20];
char prenom[20];
char numTel[11];
char mel[50];
char motdepasse[9];
} contact_t;
contact_t tab[N];
Pour le fichier:
fopen( "leFichier.truc", "wb" ); et fopen( "leFichier.truc", "rb" );
fwrite( tab + i, sizeof( contact_t ), 1, fichier );
fread( tab + i, sizeof( contact_t, 1, fichier );
Inconvénient: le fichier est plus gros car les 110 octets maximums de la structure sont toujours écrits; Le fichier ne peut pas être éditer dans un blocnote ou autre.
Avantage: plus simple, plus sûr, plus opaque (il faut un éditeur héxa), on peut envisager de ne lire que le contact 7 sans parcourir tout le fichier.
Comme les contacts sont dans un tableau on peut aussi faire sauter la boucle for:
void enregistrement(int *nbContact) { FILE *fichier = fopen(chemin,"wb"); if ( fichier != NULL ) { fwrite( nbContact, sizeof( *nbContact ), 1, fichier ); fwrite( tab, sizeof( contact_t ), *nbContact, fichier ); fclose(fichier); } }
La fonction de lecture a à peu près la même tête avec un "rb" et des fread.
On peut vérifier le nombre d'objets lus avec succès grace à la valeur de retour pour éventuellement corriger le nbContacts en cas de problème du fichier.
M.
Fait donc, en plus je suis de mauvais poil aujourd'hui, je ne vais rien laisser passer. Attention si il manque des point-virgules, je mords.
M.
M.
J'ai pas trop envie de me faire croquer lol
Juste une petite kestion dans le message précédent tu as mis : fwrite( nbContact, sizeof( *nbContact ), 1, fichier );
A quoi correspond le 1? Tu peux m'expliquer comment s'utilise fwrite et fread s'il te plait parce que je ne sais pas si ca ira avec ce que je faisais au début c'est à dire mettre le contenu du fichier dans les variables dans la fonction fichierVariable
Juste une petite kestion dans le message précédent tu as mis : fwrite( nbContact, sizeof( *nbContact ), 1, fichier );
A quoi correspond le 1? Tu peux m'expliquer comment s'utilise fwrite et fread s'il te plait parce que je ne sais pas si ca ira avec ce que je faisais au début c'est à dire mettre le contenu du fichier dans les variables dans la fonction fichierVariable
Ah bah je vois que mes liens sur fread/fwrite ont servis. ^^ Héhé.
Le premier paramètre est le buffer de données, le deuxième la taille d'une donnée, le troisième le nombre d'objets de la taille précédemment spécifiée et le quatrième le fichier. La valeur de retour est le nombre d'objets écrits avec succès.
Il y a des cas où l'on n'a pas de buffer avec toutes les données les unes à la suite des autres et donc prêtes à écrire toutes d'un coup. Dans ce cas on fera un for pour les écrire une par une. (d'où le 1) Si par chance elles sont consécutives dans la mémoire on fera l'écriture en une fois comme dans l'exemple du précédent post.
En mode binaire les données dans le fichier sont une copie exacte des données dans la mémoire:
- Les tableaux de 20 caractères seront écrits sur 20 octets même si c'est pour coder "Bonjour".
- Les entiers seront codés sur 4 octets. (généralement, en fait c'est le développeur qui précise)
A l'inverse en mode texte, "Bonjour" est codé sur 8 octets et 123456789 sera écrit sur 9 octets.
M.
EDIT. :
Whoups, en plus je lis mal la question.
La ligne que tu as reprise dans ton poste écrit le nombre de contacts au début du fichier. A savoir comme paramètres : l'adresse de ta variable, sa taille en octets et 1 car il n'y a qu'un seul nombre à écrire.
Le premier paramètre est le buffer de données, le deuxième la taille d'une donnée, le troisième le nombre d'objets de la taille précédemment spécifiée et le quatrième le fichier. La valeur de retour est le nombre d'objets écrits avec succès.
Il y a des cas où l'on n'a pas de buffer avec toutes les données les unes à la suite des autres et donc prêtes à écrire toutes d'un coup. Dans ce cas on fera un for pour les écrire une par une. (d'où le 1) Si par chance elles sont consécutives dans la mémoire on fera l'écriture en une fois comme dans l'exemple du précédent post.
En mode binaire les données dans le fichier sont une copie exacte des données dans la mémoire:
- Les tableaux de 20 caractères seront écrits sur 20 octets même si c'est pour coder "Bonjour".
- Les entiers seront codés sur 4 octets. (généralement, en fait c'est le développeur qui précise)
A l'inverse en mode texte, "Bonjour" est codé sur 8 octets et 123456789 sera écrit sur 9 octets.
M.
EDIT. :
Whoups, en plus je lis mal la question.
La ligne que tu as reprise dans ton poste écrit le nombre de contacts au début du fichier. A savoir comme paramètres : l'adresse de ta variable, sa taille en octets et 1 car il n'y a qu'un seul nombre à écrire.
Donc si j'ai bien compri
Comment faire pour ouvrir un fichier en écriture c'est "wb" c'est bien ça? Est-ce que ça efface les données précédentes? Je reste un peu perdue, donc en gros l'utilisation du binaire va t-il changer complétement mon programme, seuls les fonctions enregistrement et fichierVariable sont modifiées n'est ce pas ou il faut recommencer c'est à dire saisir les informations directement dans le fichier et les lire dans le fichier.
fwrite( tab, sizeof( contact_t ), *nbContact, fichier );copie tout le tableau dans le fichier?
Comment faire pour ouvrir un fichier en écriture c'est "wb" c'est bien ça? Est-ce que ça efface les données précédentes? Je reste un peu perdue, donc en gros l'utilisation du binaire va t-il changer complétement mon programme, seuls les fonctions enregistrement et fichierVariable sont modifiées n'est ce pas ou il faut recommencer c'est à dire saisir les informations directement dans le fichier et les lire dans le fichier.
C'est bien ça.
Plus précisément on recopie octet par octet les *nbContact contacts du tableau dans le fichier.
L'ouverture en écriture est bien "wb". Tu peux te référer à la MSDN sur fopen.
L'option w crée ou ouvre un fichier en détruisant son contenu.
Pour concaténer à la fin d'un fichier tu peux utiliser "a" (et même "ab" ici) Ceci dit je trouve mieux dans ton cas de ré-écrire le fichier complet à chaque fois.
Le mode binaire change:
- Le mode d'ouverture (donc le b dans "wb" et "rb") Le mode Texte est celui par défaut, pour dire "Texte" explicitement c'est "wt" et "rt". (Oui, ça ne sert à rien)
- Les fonctions d'écriture et de lecture.
fprintf, fputs, fputc, fscanf, fgets, fgetc en mode texte.
fread, fwrite en mode binaire.
Il y a une précaution supplémentaire à avoir avec le mode binaire :
En mode texte on aurait un fichier avec deux caractères, 2 et 2. (soit 50 et 50 en ASCII ou en binaire)
En mode binaire on aurait une suite d'octets: (j'écris en héxadécimal c'est plus simple)
16 00 00 00 sur une machine où le long int est sur 4 octets (Windows 32 bits par exemple)
16 00 00 00 00 00 00 00 sur un Windows 64 bits.
(le mode texte vu en héxa serait 32 32.)
C'est la seule chose dont il faut se méfier par rapport au mode texte. Il faut juste s'assurer que l'on prends des types équivalents dans les versions 32 et 64 bits. On définira souvent un type typedef long int i32; afin de bénéficier d'un type dont la taille est connue. Pour compiler en 64 bits on changera juste la définition du type.
D'après mes souvenirs le mode texte ou binaire ne change que deux de tes fonctions.
Bien mangé ?
(Moi j'y vais)
M.
PS: Alors ? On a perdu son mot passe ? :P
Plus précisément on recopie octet par octet les *nbContact contacts du tableau dans le fichier.
L'ouverture en écriture est bien "wb". Tu peux te référer à la MSDN sur fopen.
L'option w crée ou ouvre un fichier en détruisant son contenu.
Pour concaténer à la fin d'un fichier tu peux utiliser "a" (et même "ab" ici) Ceci dit je trouve mieux dans ton cas de ré-écrire le fichier complet à chaque fois.
Le mode binaire change:
- Le mode d'ouverture (donc le b dans "wb" et "rb") Le mode Texte est celui par défaut, pour dire "Texte" explicitement c'est "wt" et "rt". (Oui, ça ne sert à rien)
- Les fonctions d'écriture et de lecture.
fprintf, fputs, fputc, fscanf, fgets, fgetc en mode texte.
fread, fwrite en mode binaire.
Il y a une précaution supplémentaire à avoir avec le mode binaire :
long int i = 22; // Perdu ! je ne suis pas né un 22 ;-) fwrite( &i, sizeof( long int ), 1, monFichier );
En mode texte on aurait un fichier avec deux caractères, 2 et 2. (soit 50 et 50 en ASCII ou en binaire)
En mode binaire on aurait une suite d'octets: (j'écris en héxadécimal c'est plus simple)
16 00 00 00 sur une machine où le long int est sur 4 octets (Windows 32 bits par exemple)
16 00 00 00 00 00 00 00 sur un Windows 64 bits.
(le mode texte vu en héxa serait 32 32.)
C'est la seule chose dont il faut se méfier par rapport au mode texte. Il faut juste s'assurer que l'on prends des types équivalents dans les versions 32 et 64 bits. On définira souvent un type typedef long int i32; afin de bénéficier d'un type dont la taille est connue. Pour compiler en 64 bits on changera juste la définition du type.
D'après mes souvenirs le mode texte ou binaire ne change que deux de tes fonctions.
Bien mangé ?
(Moi j'y vais)
M.
PS: Alors ? On a perdu son mot passe ? :P
Ok ok, j'ai compri donc un petit exemple, si je veux écrire le nombre de contact dans la variable *nbContact, je dois la lire dans le fichier puis l'écrire , ca donne ça : fread(*nbContact, sizeof(*nbContact),1,fichier)? Ceci me parait bien bizar!!!! j'ai du me tromper à sizeof(*nbContact).
J'ai retrouvé mon mot de passe :).
Le repas était des plus délicieux lol.
Bon appétit
J'ai retrouvé mon mot de passe :).
Le repas était des plus délicieux lol.
Bon appétit
C'est presque ça.
C'est juste le premier paramètre, il lui faut une adresse vers une zone mémoire dans laquelle il peut écrire. (Tout comme scanf) Il y a donc juste une * en trop.
Le sizeof est bon. On pourrait mettre sizeof( int ) puisque c'est la taille en nombre d'octets d'un élément du buffer mais je préfère mettre par rapport à la variable, cela évite d'oublier de le changer si on modifie le type de la variable.
Pour la lecture, seul le nom de la fonction a changé. (et le w/r du fopen évidement)
On peut mieux faire: (Et là moi J'♥ ! D'ailleurs on peut le mettre aussi pour l'écriture)
Le nombre d'éléments est la taille du tableau en octets divisé par la taille d'un élément.
Et voilà,
Ca fera 350€ ^^
Si il y a toujours un truc qui te chagrine... je repasserai demain soir.
(C'est plus fort que moi, j'aime pas les chagrinées. >_<)
Bonne soirée à toi,
M.
C'est juste le premier paramètre, il lui faut une adresse vers une zone mémoire dans laquelle il peut écrire. (Tout comme scanf) Il y a donc juste une * en trop.
Le sizeof est bon. On pourrait mettre sizeof( int ) puisque c'est la taille en nombre d'octets d'un élément du buffer mais je préfère mettre par rapport à la variable, cela évite d'oublier de le changer si on modifie le type de la variable.
#include <stdio.h> #include <string.h> int main () { FILE *pFile = NULL; char *szFile = "test.truc"; // Des variables à écrire. unsigned int uMyValue = 22; char cMyChar = 'A'; int aiMyIntArray[] = { 1, 9, 2, 8 }; ////////////// // Ecriture // ////////////// pFile = fopen( szFile, "wb" ); if ( pFile != NULL ) { // Le int. fwrite( &uMyValue, sizeof( uMyValue ), 1, pFile ); // Le char. fwrite( &cMyChar, sizeof( cMyChar ), 1, pFile ); // Le tableau de int. fwrite( aiMyIntArray, sizeof( *aiMyIntArray ), 4, pFile ); // Ou (moins beau à mon goût) // fwrite( aiMyIntArray, sizeof( aiMyIntArray ), 1, pFile ); fclose( pFile ); } // On écrase les variables. uMyValue = 0; cMyChar = 0; memset( aiMyIntArray, 0, sizeof( aiMyIntArray ) ); ///////////// // Lecture // ///////////// pFile = fopen( szFile, "rb" ); if ( pFile != NULL ) { // Le int. fread( &uMyValue, sizeof( uMyValue ), 1, pFile ); // Le char. fread( &cMyChar, sizeof( cMyChar ), 1, pFile ); // Le tableau de char. fread( aiMyIntArray, sizeof( *aiMyIntArray ), 4, pFile ); // Ou // fread( aiMyIntArray, sizeof( aiMyIntArray ), 1, pFile ); fclose( pFile ); } printf( "Les valeurs sont :\n%d\n%c\n{ %d, %d, %d, %d }\n", uMyValue, cMyChar, aiMyIntArray[0], aiMyIntArray[1], aiMyIntArray[2], aiMyIntArray[3] ); getchar(); return 0; }
Pour la lecture, seul le nom de la fonction a changé. (et le w/r du fopen évidement)
On peut mieux faire: (Et là moi J'♥ ! D'ailleurs on peut le mettre aussi pour l'écriture)
fread( aiMyIntArray, sizeof( *aiMyIntArray ), sizeof( aiMyIntArray ) / sizeof( *aiMyIntArray ), pFile );
Le nombre d'éléments est la taille du tableau en octets divisé par la taille d'un élément.
Et voilà,
Ca fera 350€ ^^
Si il y a toujours un truc qui te chagrine... je repasserai demain soir.
(C'est plus fort que moi, j'aime pas les chagrinées. >_<)
Bonne soirée à toi,
M.