[C] Lire un fichier . txt

Fermé
Thibaut - 23 janv. 2010 à 19:13
 jovenix - 25 janv. 2010 à 19:50
Bonjour,
J'ai suivit des cours basique de programation en language C et j'ai un projet à rendre pour lundi matin !!
Aucun probléme pour ECRIRE mais je rencontre un probléme pour LIRE dans un fichier .txt et j'ai vraiment besoin de votre aide en tout urgence (Il reste du boulot et j'ai déja passer plusieur heures sur ce probléme) !

Le sujet : Coder un programme capable de gérer la location de voitures ... (Je vous la fait courte ^^) !


MON PROBLÈME :
Je me sert d'une "base de données" contenu dans un fichier .txt contenant les infos de chaque clients sur une unique ligne
EXEMPLE : (deux clients, dans l'ordre : leurs n° d'identifiant, nom, prenom, tel)
ID;1;PERRON;Lucas;0189632147;
ID;2;PARIN;Pierre;0647475814;


J'utilise donc une structure :

typedef struct
{
int idEmploye;
char nom[100];
char prenom[100];
int tel;
int nbrKmEmploye;
int nbrAccident;
}Employe;

Le principe c'est que j'appel la base de donner en tout début de programme pour remplir les cases du tableau (dont j'ai besoin par la suite) :
Employe tabEmploye[100];
(Dans notre cas seul les 2 premieres cases seront utilisées)

Voici mon code, je compte sur vous pour me dire ce qu'il ne va pas :)


void miseAJourInitiale ()
{
int i;
char tampon[100]; // Pour eviter un bug qui lit tout la ligne lors du 1er fscanf d'un char

FILE *fichier1;
fichier1=fopen("véhicules.txt","r");

if(fichier1==NULL)
fclose(fichier1);
else
{
for (i=1; i<100; i++)
{
if (getc(fichier1) != EOF)
{
fseek(fichier1,2, SEEK_CUR);
fscanf(fichier1,"%d;",&tabEmploye[i].idEmploye);
fscanf(fichier1,"%s;",&tampon);
fscanf(fichier1,"%s;",&tabEmploye[i].nom);
fscanf(fichier1,"%s;",&tabEmploye[i].prenom);
fscanf(fichier1,"%d;",&tabEmploye[i].tel);
fscanf(fichier1,"%d;",&tabEmploye[i].nbrKmEmploye);
fscanf(fichier1,"%d;",&tabEmploye[i].nbrAccident);

printf("\n..%d..%s..%s..%d..%d..%d..\n", tabEmploye[i].idEmploye, tabEmploye[i].nom, tabEmploye[i].prenom, tabEmploye[i].tel, tabEmploye[i].nbrKmEmploye, tabEmploye[i].nbrAccident);
}
}
system("PAUSE");
}

fclose(fichier1);

}


Le programme me donne un résultat abérant, ne prennant pas en compte les char (Et les int sont faux ^^)
..1......0..0..

PS : je n'ai méme pas encore codé pour rentrer les valeur dans le tableau car les données lut sont erronées vu le résultat du printf ....

Je ne peut pas continuer sans votre aide :s
Un énorme merci par avance
A voir également:

3 réponses

RESOLU :

Le tampon ne sert a RIEN
Le ; induisait en erreur car il ne separe pas bien les char !
En mettant des espaces tout roule !

Voici le bon code :

Code :

1. typedef struct
2. {
3. int idEmploye;
4. char nom[100];
5. char prenom[100];
6. int nbrKmEmploye;
7. }Employe;
8.
9.
10.
11. Employe tabEmploye[100];
12.
13.
14. void main ()
15. {
16. int i;
17.
18. FILE *fichier1;
19. fichier1=fopen("employés.txt","r" );
20.
21. if(fichier1!=NULL)
22. {
23. for (i=1; i<100; i++)
24. {
25. if (getc(fichier1) != EOF)
26. {
27. fscanf(fichier1,"D;%d;%d;%s %s\n",&tabEmploye[i].idEmploye, &tabEmploye[i].nbrKmEmploye, tabEmploye[i].nom, tabEmploye[i].prenom);
28.
29.
30. printf("\n..%d..%d..%s..%s..", tabEmploye[i].idEmploye, tabEmploye[i].nbrKmEmploye, tabEmploye[i].nom, tabEmploye[i].prenom);
31. system("PAUSE" );
32. }
33. }
34. }
35. fclose(fichier1);
36.
37.
38. }



Avec, ecrit au préalable dans le fichier txt :
ID;1;47;AA CC
ID;3;74;BB DD

La console affiche bien :
..1..47..AA..CC..
..3..74..BB..DD..


Bonne soirée
1
A noté que quand je fait des fprintf avec pour rentrer tout les données juste avant mes fscanf ca marche parfaitement bien ...

Par contre quand je fait que de la lecture au début (donc sans écriture juste avant) ca ne marque plus et j'ai des valeures abhérantes !
0
loupius Messages postés 697 Date d'inscription dimanche 1 novembre 2009 Statut Membre Dernière intervention 31 décembre 2017 148
23 janv. 2010 à 23:27
Je ne vois pas d'erreurs dans ton programme mais je ne dis pas qu'il n'y en ait pas.
Toutefois, à moins que ce soit un exercice de style, je n'utiliserais pas le couple 'fseek/fscanf'. Pourquoi ? Il y a 2 raisons:
- lire des chaînes avec des 'scanf' est terriblement dangereux et devrait être proscrit comme des 'gets',
- utiliser des 'fseek' pour sauter les fins de chaîne pose 2 problèmes: dépend du système d'exploitation (1 caractère sous Linux et 2 sous Windows) et ne permet pas une resynchronisation s'il y a une erreur dans une des lignes du fichier.
Ce sont pour ces raisons que j'utiliserais plutôt le couple fgets/strchr:
- 'fgets' pour lire une ligne entière,
- 'strchr' pour découper la ligne en différents champs.

Nota: 2 petits détails:
FILE *fichier1=fopen("véhicules.txt","r");
if(fichier1==NULL)
fclose(fichier1);

Il est absurde de fermer un fichier ... qui n'a pas pu être ouvert ;-)
Il vaut mieux avoir la structure suivante:
FILE* fichier1 = fopen("véhicules.txt", "r");
if (fichier1)
{
  ...
  fclose(fichier1);
}
char tampon[100];
for (i=1; i<100; i++)

Pour remplir raisonnablement le tableau, l'indice 'i' doit aller de '0' à '<100'.
Bonne continuation.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 836
24 janv. 2010 à 01:19
Hello,
- utiliser des 'fseek' pour sauter les fins de chaîne pose 2 problèmes: dépend du système d'exploitation (1 caractère sous Linux et 2 sous Windows)
Non. A moins d'ouvrir le fichier en binaire, en C le retour chariot sera '\n' quelque soit le système d'exploitation. fseek n'a donc aucun problème pour "sauter les fins de chaîne".

Cdlt,
0
loupius Messages postés 697 Date d'inscription dimanche 1 novembre 2009 Statut Membre Dernière intervention 31 décembre 2017 148 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
24 janv. 2010 à 03:12
Sous Windows, je ne sais comment cela se passe.
Sous Linux, le mode 'texte' n'existe pas; tout fichier est donc ouvert en mode binaire. J'ai été obligé de faire des essais car il y a bien longtemps que je ne me suis pas préoccupé de ce problème. Voici mes observations avec un fichier contenant des '0A' et des '0D'.
- La fonction 'fseek' ne fait aucune différence entre les octets, il les compte tous,
- La fonction 'fgets' s'arrête bien aux '0A' et les laisse dans la chaîne, d'autre part elle considère le '0D' comme un caractère et le laisse donc aussi dans la chaîne; par contre, seul le '0A' sert de délimiteur de ligne.
Finalement il n'y a rien d'étonnant puisque le fichier est ouvert en binaire; le problème c'est qu'il s'agit du seul mode existant. Personnellement, je trouve cela plus simple.
Bonne nuit.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 836 > loupius Messages postés 697 Date d'inscription dimanche 1 novembre 2009 Statut Membre Dernière intervention 31 décembre 2017
24 janv. 2010 à 08:16
Sous Linux, le mode 'texte' n'existe pas; tout fichier est donc ouvert en mode binaire
Oui mais comme sous Linux le retour chariot est '\n' comme en C, cela ne pose absolument aucun soucis.

En revanche sous windows, l'ouverture du fichier en mode binaire et en mode texte aura une incidence sur la gestion des retours chariots. "\r\n" transformé en "\n" en lecture et inversement en écriture.

Il n'y a donc aucun problème d'utilisation de fseek et c'est heureux.
0