IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Est-ce une bonne utilisation de fgets ?


Sujet :

C

  1. #1
    Membre régulier Avatar de clampin
    Homme Profil pro
    Inscrit en
    Février 2005
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2005
    Messages : 96
    Points : 105
    Points
    105
    Par défaut Est-ce une bonne utilisation de fgets ?
    Salut,

    Après quelques semaine de cours de langue intensif, je reprends mon apprentissage en auto-didacte du C.

    Et j'ai donc pondu un petit programme de recherche de caractère basé sur un exemple de mon bouquin.

    Je me demande si j'ai bien compris l'utilisation de fgets

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    #include <stdio.h>
    #include <string.h>
     
    int main(void)
    {
    	char *loc, buf[80];
    	int ch;
     
    	printf("tapez la chaîne de caractère : ");
    	fgets(buf,80,stdin);
    	printf("tapez le caractère a trouver : ");
    	ch = getchar();
     
    	loc = strchr(buf, ch);
     
    	if (loc == NULL)
    		printf("On n'a pas trouvé le caractère %c", ch);
    	else
    		printf("Le caractère %c a été trouvé en position %d\n", ch, loc-buf);
     
    	return 0;
    }
    Bon visiblement le programme compile bien sur mon Mac, mais est-ce j'ai bien utilisé fgets... ou bien aurais-je du utilisé une autre fonction de saisie ?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    C'est bien fgets() qu'il faut utiliser, mais ton utilisation ne prend pas tout en compte:
    • Notamment, si la chaîne tapée fait moins de 80 caractères, le \n sera inclus dedans.
    • Sinon, les caractères non-lus seront toujours dans le buffer d'entrée du terminal (le le getchar() sera alors non-bloquant).

    Pour résoudre ces problèmes, on se fait généralement une fonction qui vide la ligne courante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    int PurgeStream(FILE *pfIn)
    {
    	int c;
    	do
    	{
    		c = fgetc(pfIn);
    	} while(c != '\n' && c != EOF);
    	if(c==EOF)
    		return -1;
    	return 0;
    }
    Et ensuite, on se fait souvent une fonction à utiliser après chaque fgets(). Là, ce qui arrive au 'reste' de la ligne dépend de ce que veut le programmeur:
    • Soit on l'ignore (le plus simple)
    • soit on joue avec l'allocation dynamique pour retourner toute la ligne (avancé, et il faut connaitre l'allocation dynamique).

    Dans le cas simple, une fonction comme celle-ci suffit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <string.h>
    #include <stdio.h>
     
    int PurgeStream(FILE*);
     
    int PurgeLineAndStream(char *buf, FILE *pfIn)
    {
    	int ret = 0;
    	char *pLF = strchr(buf, '\n'); /* Cherche le \n */
    	if(pLF != NULL)
    	{
    		/* Trouvé: Toute la ligne a été lue, on tronque la chaîne */
    		*pLF = '\0';
    	}
    	else
    	{
    		/* Non-trouvé: Il reste des caractères dans le buffer */
    		ret = PurgeStream(pfIn);
    	}
    	return ret;
    }
    Et ça s'utilise ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <stdio.h>
    #include <string.h>
     
    int PurgeStream(FILE*);
    int PurgeLineAndStream(char *, FILE *);
     
    int main(void)
    {
    	char *loc, buf[80];
    	int ch;
     
    	printf("tapez la chaîne de caractère : ");
    	fgets(buf,80,stdin);
    	PurgeLineAndStream(buf, stdin);
     
    	printf("tapez le caractère a trouver : ");
    	ch = getchar();
    	PurgeStream(stdin);
     
    	loc = strchr(buf, ch);
     
    	if (loc == NULL)
    		printf("On n'a pas trouvé le caractère %c\n", ch);
    	else
    		printf("Le caractère %c a été trouvé en position %d\n", ch, loc-buf);
     
    	return 0;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Et je conseille également, du moins juste par souci de maintenabilité du code, de toujours faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets(buffer, sizeof(buffer), stdin);

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    +1 Melem.
    Sauf que pour des raisons de passage éventuel à unicode, je conseillerais plutôt l'utilisation d'une macro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifndef ARRAYSIZE
    #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
    #endif
     
    ...
    fgets(buffer, ARRAYSIZE(buffer), stdin);
    Note: Cela ne marque que sur les tableaux. Sur un pointeur, c'est la taille du pointeur qui sera prise en compte à la place.
    En C++ il y a des ruses pour corriger ce problème, mais pas en C...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Ouais. Et pour loc - buf aussi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (loc - buf)/sizeof(buf[0])

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Melem
    Ouais. Et pour loc - buf aussi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (loc - buf)/sizeof(buf[0])
    NON : Lors d'une soustraction de pointeurs, la division est comprise.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Médinoc
    NON : Lors d'une soustraction de pointeurs, la division est comprise.
    Donc (p + 1) - p vaut 1 et non sizeof(*p)?

  8. #8
    Membre régulier Avatar de clampin
    Homme Profil pro
    Inscrit en
    Février 2005
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2005
    Messages : 96
    Points : 105
    Points
    105
    Par défaut
    Merci de vos réponses.... J'ai encore appris grâce a vous....

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Melem
    Donc (p + 1) - p vaut 1 et non sizeof(*p)?
    Oui (confirmé par tests).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/01/2009, 22h45
  2. [Python] Est-ce une bonne idée d'utiliser des modules pour stocker des objets ?
    Par Neolander dans le forum Développement 2D, 3D et Jeux
    Réponses: 1
    Dernier message: 05/04/2008, 14h45
  3. Est ce une bonne idée utiliser Java?
    Par solaar dans le forum Langage
    Réponses: 8
    Dernier message: 22/03/2008, 16h28
  4. [AS2] Conseils pour une bonne utilisation de la POO
    Par guy2004 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 9
    Dernier message: 20/03/2006, 08h24
  5. [Singleton] En faire une bonne utilisation
    Par Koubi dans le forum Langage
    Réponses: 6
    Dernier message: 01/09/2005, 17h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo