Se connecter / S'enregistrer
Votre question

Langage C (saisie de données sur fichier)

Tags :
  • Programme
  • Programmation
Dernière réponse : dans Programmation
1 Avril 2005 14:44:00

Bonjour à tous ! Je bloque sur mon programme en langage C. Je suis novice !
Je dois créer un programme où l'on rentre : nom, prénom, ville, adresse, code postal, téléphone et anniversaire. Pour cela j'utilise une structure. Jusqu'à présent tout va bien ! Maintenant je dois contrôler la saisie afin d'éviter que la chaîne de caractère entrée ne depasse pas mon tableau. Et je dois rentrer tout cela dans un fichier. J'avais penser à la fonction "fgets" mais pas moyen de la comprendre. jai essayé beaucoup de choses comme "getche","gets"... Mais en vain.
Voici mon prgramme en C :

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


struct personne /* D‚claration de la structure personne */
{
char fnom[20];
char pnom[20];
int phone[10];
char adresse[60];
char ville[15];
int code[5];
int jour[2];
int mois[2];
int annee[4];
};

struct personne list[200]; /* D‚claration du nombre de contact que contiendra le tableau */


main()
{

FILE*saisie;

/*D‚claration des variables*/
char pnom[20],fnom[20],phone[10],adresse[60],ville[15],code[5],jour[2],mois[2],annee[4];

int i,nbre;

clrscr();

saisie=fopen("resultat.dat","wt");

printf("Entrez le nombre de personnes : "); /* Nombre de personnes … ajouter */
scanf("%d",&nbre);
printf("________________________________");
for(i=0;i<nbre;i++)
{
printf(" \n \n \nEntrez le nom : "); /* Saisie des infos concernant la personne */
scanf("%s",list.fnom);
printf("Entrez le pr‚nom : ");
scanf("%s",list.pnom);
printf("Entrez le num‚ro de t‚l‚phone (xxxxxxxx) : ");
scanf("%s",list.phone);
printf("Entrez l'adresse : ");
scanf("%s",list.adresse);
printf("Entrez la ville : ");
scanf("%s",list.ville);
printf("Puis le code postal : ");
scanf("%s",list.code);
printf("Vous allez entrer la date de naissance (xx/xx/xxxx)\n");
printf("Entrez le jour de la date de naissance : ");
scanf("%s",list.jour);
printf("Entrez le mois de la date de naissance : ");
scanf("%s",list.mois);
printf("Entrez l'ann‚e de la date de naissance : ");
scanf("%s",list.annee);
}

/* Affichage des infos concernant la personne */
for(i=0;i<nbre;i++)
{
fprintf(saisie,"\n \nContact : %s %s \n",list.pnom,list.fnom);
fprintf(saisie,"T‚l‚phone : %s \n",list.phone);
fprintf(saisie,"Adresse : %s %s %s\n",list.adresse,list.ville,list.code);
fprintf(saisie,"Date de naissance : %s/%s/%s \n",list.jour,list.mois,list.annee);
}
fclose(saisie);
}


Merci d'avance à tous !

Autres pages sur : langage saisie donnees fichier

a b L Programmation
1 Avril 2005 18:04:40

Utilise:
scanf ("%4s", var);
pour ne prendre que 4 caractères

par contre, après chaque scanf, pense à mettre un fflush (stdin);

parce que si tu fait:
scanf ("%4s", var1);
scanf ("%4s", var2);
printf ("%s....%s\n", var1, var2)

et que l'utilisateur tape "azerty" + entrée, la première variable var1 est remplie à "azer", mais comme le buffer clavier est plein, il va directement remplir var2 par "ty" sans rien demander à l'utilisateur.

avec ceci:
scanf ("%4s", var1);
fflush (stdin);
scanf ("%4s", var2);
fflush (stdin);
printf ("%s....%s\n", var1, var2)

si l'utilisateur tape "azerty", var1 contiendra "azer", puis on vide le buffer clavier, et l'utilisateur doit rentrer la seconde var par ex "qsdfghj" et var2 contiendra "qsdf".
2 Avril 2005 14:26:32

Merci pour ta solution, par contre il y a 2 petits problème :s

->je reprend ton exemple : "si l'utilisateur tape "azerty", var1 contiendra "azer", puis on vide le buffer clavier, et l'utilisateur doit rentrer la seconde var par ex "qsdfghj" et var2 contiendra "qsdf"." Lorsque j'enregistre cela dans mon fichier, je visualise : azerqsdf
qsdf
Par contre si je rentre moins de 4 caractères pour var1 et pour var2, je visualise bien : azer
qsdf

-> Lorsque je saisie une chaine de caractères ( par exmple la'dresse ou un nom composé) l'espacement me fais passer à la saisie suivante et donc ne tient pas en compte la suite ma chaine.
Contenus similaires
a b L Programmation
3 Avril 2005 12:42:45

Effectivement je n'avait pas pensé à ça.
En fait "Entrée" est un caractère '\n'
Donc, quand ça coupe le mot, il n'y a aucun caractères '\n' à la fin, donc dans ton fichier ça ne retourne pas à la ligne.

donc voici l'exemple correct:
char var1 [5];
char var2 [5];

scanf ("%4s", var1);
/* ici les caractères 0,1,2,3 sont remplies */
/* on ajoute le retour chariot */
var1 [4] = '\n';
fflush (stdin);
scanf ("%4s", var2);
var2 [4] = '\n';
fflush (stdin);
printf ("%s....%s\n", var1, var2)

si l'utilisateur ne rentre que "aa" pour var1, l'utilisateur à enfait entré: 'a' 'a' '\n'
donc la chaine sera: 'a' 'a' '\n' ? '\n'
ce qui en fait vaut 'a' 'a' '\n'

Il n'y a pas de moyen simple pour bloquer le curseur au bout de temps de caractères (je ne vois que l'assembleur pour faire ça).
sinon tu peux prendre 21 caractères (sur un char [22]), et si la taille de la chaine (strlen ()) dépasse 20, tu peux ajouter un système de controle et prévenir l'utilisateur.
12 Avril 2005 16:12:33

si j'ai bien compris ton probleme, il te faut créer une boucle qui parcourt ta chaine du style:

lg =strlen(chaine);

for (i=0;i<lg;i++)
{ putchar(chaine);}

chaine='\0'; => fin de la chaine! // il ne faut pas oublier que le c considere une chaine de caracteres come un tableau et que si on nous lui dis pas où s'arrete la chaine en memoire il affiche des données se trouvant a coté en memoire.


j'ai pas lu tout ton prog mais je pense que ton probleme viens de là...
a b L Programmation
12 Avril 2005 17:39:10

Exact la solution de issou est la mieux :-)
13 Avril 2005 18:04:19

Merci beaucoup ! Je vais essayer ça dès que je peux !
:gg:
14 Avril 2005 02:42:19

j'ai essayer ce que tu me propose issou mais j'ai beaucoup de warning :s ! je dois surement mal utiliser ta solution :
"
printf("Entrez le prénom : ");
long=strlen(pnom);
for (i=0;i<long;i++)
{ putchar(list.pnom);}
"
14 Avril 2005 02:49:20

Citation :

issou a écrit :
chaine='\0'; => fin de la chaine! // il ne faut pas oublier que le c considere une chaine de caracteres come un tableau et que si on nous lui dis pas où s'arrete la chaine en memoire il affiche des données se trouvant a coté en memoire.


D'autant que le comportement diffère suivant les compilos !

Sur un gcc-2.95, sans \0 à la fin de ma chaine j'avais pas de problème. j'essaye sur un gcc-3.3.5, paf ça merde ... Et comme je suis pas un dieu en C, on m'a indiqué qu e c'était le problème :) 
a b L Programmation
14 Avril 2005 10:59:28

Lissyx, le problème vient de l'initialisation de l'espace mémoire d'adresse "chaine".
Probablement que gcc-2.95 initialisait chaine à '\0', '\0', ..., '\0', alors que gcc-3.3.5 n'initialise pas la chaine en la laissant à ?,?,...,?, donc peut de chance pour qu'il y ait un '\0' en fin de chaine ;-)
C'est mieux que ce ne soit pas initialisé à 00...0: ça optimise le code (une ligne d'assembleur en moins :-D )

Doggy, quel est le premier warning ? et donne la ligne de code qui correspond :-)
14 Avril 2005 13:35:37

Moi j'utilise Turbo C 2.01 ! Eh oui ce vieux machin ! :p 
Voila mon premier warning :
il m'indique : " Expression syntax in function main" en pointant en rouge mon " = " de la ligne :
"long=strlen(list.fnom);"

Je vous donne mon prog , je pense que ça sera plus simple à comprendre ;) 


#include<stdio.h>
#include<stdlib.h>
#include<string.h>


struct personne /* D‚claration de la structure personne */
{
char fnom[20];
char pnom[20];
int phone[10];
char adresse[60];
char ville[15];
int code[6];
int jour[3];
int mois[3];
int annee[5];
};

struct personne list[200]; /* D‚claration du nombre de contact que contiendra le tableau */


main()
{

FILE*saisie;

/*D‚claration des variables*/
int i,nbre;
int long;

clrscr();

saisie=fopen("resultat.dat","wt");

printf("Entrez le nombre de personnes : "); /* Nombre de personnes … ajouter */
scanf("%d",&nbre);
printf("________________________________");
for(i=0;i<nbre;i++)
{
printf(" \n \n \nEntrez le nom : "); /* Saisie des infos concernant la personne */
long=strlen(list.fnom);
for (i=0;i<long;i++)
{ putchar(list.fnom]);}
list.fnom='\0';
printf("Entrez le pr‚nom : ");
long=strlen(pnom);
for (i=0;i<long;i++)
{ putchar(list.pnom);}
list.pnom='\0';
printf("Entrez le num‚ro de t‚l‚phone (xxxxxxxx) : ");
long=strlen(phone);
for (i=0;i<long;i++)
{ putchar(list.phone);}
list.phone='\0';
printf("Entrez l'adresse : ");
long=strlen(adresse);
for (i=0;i<long;i++)
{ putchar(list.adresse);}
list.adresse='\0';
printf("Entrez la ville : ");
long=strlen(ville);
for (i=0;i<long;i++)
{ putchar(list.ville);}
list.ville='\0';
printf("Puis le code postal : ");
long=strlen(code);
for (i=0;i<long;i++)
{ putchar(list.code);}
list.code='\0';
printf("Vous allez entrer la date de naissance (xx/xx/xxxx)\n");
printf("Entrez le jour de la date de naissance : ");
long=strlen(jour);
for (i=0;i<long;i++)
{ putchar(list.jour);}
list.jour='\0';
printf("Entrez le mois de la date de naissance : ");
long=strlen(mois);
for (i=0;i<long;i++)
{ putchar(list.mois);}
list.mois='\0';
printf("Entrez l'ann‚e de la date de naissance : ");
long=strlen(annee);
for (i=0;i<long;i++)
{ putchar(list.annee);}
list.annee='\0';
}

/* Affichage des infos concernant la personne */
for(i=0;i<nbre;i++)
{
fprintf(saisie,"\n \nContact : %s %s\n",list.pnom,list.fnom);
fprintf(saisie,"T‚l‚phone : %s\n",list.phone);
fprintf(saisie,"Adresse : %s %s %s\n",list.adresse,list.ville,list.code);
fprintf(saisie,"Date de naissance : %s/%s/%s \n",list.jour,list.mois,list.annee);
}
fclose(saisie);
}

En tout cas, c'est cool pour l'aide ! :D 
a b L Programmation
14 Avril 2005 14:57:03

change le nom de la variable.
'long' est aussi un type comme 'int'
appelle la variable 'longueur' :-)
15 Avril 2005 14:02:17

Bien joué !
Mais je reste encore avec 15 warning et 26 errors :haaa:
a b L Programmation
15 Avril 2005 15:39:14

Alors affiche la liste des warnings et erreurs :-D
15 Avril 2005 19:11:07

lol ! le plus simple ça serait que tu compiles mon prog :oops:  car vu le nombre de warnings , si on les traite un par un , on aura jamais finit !!
a b L Programmation
15 Avril 2005 20:09:23

Désolé mais je ne touche pas à un code comme ça (je changerais tout :-) ). Déjà les instructions qui sont répétées plusieurs fois devraient être mise dans une fonction. Ouvrir le fichier que lorsqu'on en a besoin (pas au debut, et faire des tests d'echecs)

Sans tester, en regardant un peu mieux le code, voici les problèmes que je vois:
- Tu as 2 boucles imbriquées qui utilise la même variable i... si tu modifies i dans un petit "for" tu modifie i de la boucler principale car c'est la même variable.
- Tu utilises des putchar, je pense plutot que tu veut utiliser getchar () pour récupérer l'entrée. putchar c pour mettre en sortie écran ou fichier.
- putchar prend en paramètre 1 caractère pas une chaine de caractères. Quand tu aura corrigé avec getchar au lieu de putchar tu utiliseras:
  1. printf(" \n \n \nEntrez le nom : "); /* Saisie des infos concernant la personne */
  2. longueur=strlen(list[i].fnom);
  3. for (j=0;j<longueur;j++)
  4. list[i].fnom[j] = getchar(]);
  5. list[i].fnom[j]='\0';

- le strlen ne retourne pas la longueur max mais la longueur actuelle de la chaine.

Allez je te montre comment faire ça bien:
  1. /**********************************************************
  2. * Lecture d'une chaine de caractère limitée
  3. * Paramètres : - chaine : la chaine de caractères
  4. * - nbCharMax : nombre maximal de caractères (-1 pour le maximal)
  5. * Retourne le nombre de caractères entrés
  6. **********************************************************
  7. */
  8. int GetLimitedString (char * chaine, int nbCharMax)
  9. {
  10. int i; /* itérateur */
  11. char c = 0; /* caractère entré */
  12. int longueur = nbCharMax; /* longueur maximale admissible */
  13.  
  14. if (!chaine)
  15. return 0;
  16.  
  17. if (sizeof (chaine) - 1 < nbCharMax || nbCharMax < 0)
  18. longueur = sizeof (chaine) - 1;
  19.  
  20. /* boucle sur la frappe des caractères */
  21. for ( i = 0 ; i < longueur || c != '\n' ; ++i )
  22. {
  23. /* lecture du caractère */
  24. c = getchar ();
  25. chaine[i] = c;
  26. }
  27. if (longueur > 0)
  28. chaine[i]='\0';
  29.  
  30. return i;
  31. }


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