Forum du groupe H
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Forum du groupe H

Forum d'entraide pour le groupe H de l'IUT informatique de Lannion.
 
AccueilAccueil  Dernières imagesDernières images  RechercherRechercher  S'enregistrerS'enregistrer  Connexion  
Le Deal du moment : -45%
PC Portable LG Gram 17″ Intel Evo Core i7 32 Go ...
Voir le deal
1099.99 €

 

 Un petit supplément sur les chaines de caractères.

Aller en bas 
AuteurMessage
ezano
Admin
ezano


Messages : 59
Date d'inscription : 26/11/2009
Age : 34
Localisation : Lannion

Un petit supplément sur les chaines de caractères. Empty
MessageSujet: Un petit supplément sur les chaines de caractères.   Un petit supplément sur les chaines de caractères. Icon_minitimeLun 30 Nov - 0:32

Salut,

Je suis la pour vous montrer une fonction qui permet de récuperer au clavier une chaine de caractère.

Ok on a déjà scanf();, mais pour gérer les espaces, on fait comment ?
Avec scanf(); il suffit de faire une boucle demandant à chaque fois 1 caractère à l'utilisateur, mais il faut mettre une condition dans cette boucle, par exemple continuer a demander un caractère jusqu'à ce que l'utilisateur appuie sur entrée, ce qui n'est pas pratique du tout. De plus, scanf() est bourré de faille, essayé d'entré un nombre alors que scanf attend une chaine et le prog par en vrille.

La fonction fgets(), est plus compliqué à utilisé, mais gère les espaces, est sécurisé, il n'y a aucun risque de buffer overflow.

Le prototype de la fonction:

char *fgets( char *str, int num, FILE *stream );

Le prototype peut semblé barbard comme ça, mais c'est simple.
char *str correspond à la chaine de caractère que l'on attend.
int num correspond à la taille maximal de la chaine de caractère.
FILE *stream est un pointeur sur le fichier à lire. Ca veut dire que l'on peut utilisé fgets pour lire les fichiers aussi, mais vu que l'on veut utilisé l'entrée standard qui est celle du clavier, il faut écrire "stdin".

Bon, quoi de mieux qu'un exemple ?

Code:
#include <stdio.h>
#include <stdlib.h>

#define TAILLE 100

int main()
{
   char chaine[TAILLE];
   
   puts("What is your name:");
   fgets(chaine, TAILLE, stdin);
   printf("Ok welcome %s, king of the kaamelo\nt", chaine);

   return EXIT_SUCCESS;
}

Voila ce que donne l'execution:
Code:
ezano@machineGun:~$ ./test
What is your name:
arthur
Ok welcome arthur
, king of the kaamelot
ezano@machineGun:~$

Tout beigne, la fonction fonctionne =)

fgets est donc mieux que scanf, cependant, elle a un petit défaut que l'on peut régler, elle garde le saut de ligne en mémoire lorsque l'on appuie sur entrée, c'est pour sa que ma phrase est coupé en deux dans l'exemple du dessu.
Si on veut regler ce problème, il faut rechercher le caractère '\n' dans la chaine pour le remplacer par le caractère de fin de chaine '\0'.
Pour cela on utilise la fonction strchr(), en incluant string.h et le tour est joué.

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

#define TAILLE 100

int main()
{
   char chaine[TAILLE], *positionEntree = NULL;
   
   puts("What is your favorite color:");
   
   if(fgets(chaine, TAILLE, stdin) != NULL)
   {   
      positionEntree = strchr(chaine, '\n');
      if(positionEntree != NULL)
         *positionEntree = '\0';
   }
   
   printf("%s, is your favorite color\n", chaine);

   return EXIT_SUCCESS;
}

Voici l'execution du programme:
Code:
ezano@machineGun:~$ gcc -Wall -o test test.c
ezano@machineGun:~$ ./test
What is your favorite color:
blue   
blue, is your favorite color
ezano@machineGun:~$

Bien bien, si vous etes rendu la c'est bien ^^ mais il en reste encore un peu =)
Un autre problème de fgets, qui n'en est pas un, c'est le fait que les caractères entrés en trop par l'utilisateur sont gardé dans le buffer, en effet, si on attend une chaine de 10 caractères et que l'on en rentre 15, les 5 derniers ne seront pas affichés, c'est pour cela que fgets est sécurisé, cependant ils sont quand même présent dans le buffer, et un moyen simple de le vérifier c'est de faire exprès d'entrer trop de caractère, voici ce que ça donne.

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

#define TAILLE 10

int main()
{
   char chaine[TAILLE];
   
   puts("What is your quest:");
   fgets(chaine, TAILLE, stdin);
   printf("%s", chaine);
   puts("Hey vincent, ta déja gouté les hamburger de big kaouna ?");
   fgets(chaine, TAILLE, stdin);
   printf("%s\n", chaine);

   return EXIT_SUCCESS;
}

Voila l'execution:
Code:
ezano@machineGun:~$ gcc -Wall -o test test.c
ezano@machineGun:~$ ./test
What is your quest:
I search the graal
I search Hey vincent, ta déja gouté les hamburger de big kaouna ?
the graal
ezano@machineGun:~$

Quel bordel hein ^^ mais c'est normal, j'ai entré une chaine plus longue que prévu et fgets l'a coupé à l'affichage au 10ème caarctères, si vous en comptez que 9, c'est parce que vous avez oubliez que les tableau commence à 0, c'est cool, seulement si je rappelle fgets, je ne peut même pas taper quelques chose au clavier, comme la fonction trouve des info dans le buffer, elle s'en sert et les affiches, pour éviter ça, il faut vider le buffer.

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

#define TAILLE 10

int main()
{
   char chaine[TAILLE];
   int temp;
   
   puts("What is your quest:");
   fgets(chaine, TAILLE, stdin);
   printf("%s\n", chaine);
   
   while(temp != '\n' && temp != EOF)
      temp = getchar();
      
   puts("Hey vincent, ta déja gouté les hamburger de big kaouna ?");
   fgets(chaine, TAILLE, stdin);
   printf("%s", chaine);

   return EXIT_SUCCESS;
}

L'execution:
Code:
ezano@machineGun:~$ gcc -Wall -o test test.c
ezano@machineGun:~$ ./test
What is your quest:
I search the graal
I search
Hey vincent, ta déja gouté les hamburger de big kaouna ?
hun hun
hun hun

Voila ça fonctionne, notre phrase est coupé, parce que fgets n'atetndais que 10 caractères et on peut entrer de nouveau au clavier.
Une explication s'impose, j'ai crée une boucle qui continue tant que la variable temporaite temp n'a pas récupéré '\n' ou EOF, qui signifie, fin de chaine.
La boucle lit dans le buffer grace à la fonction getchar();, qui renvoie un entier dans temp.

Voila, avec ça, on peut manipuler les chaines de caractère à fond, sans se soucier des espaces et des buffer overflow.

Un petit code récapitulatif qui utilise tous ça peut pas faire de mal je pense, en en fonction en plus de ça =)

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

#define TAILLE 10

void viderBuffer();
void lireClavier(char chaine[]);

int main()
{
   char chaine[TAILLE];
   
   puts("What is your quest:");
   lireClavier(chaine);
   printf("%s\n", chaine);
   
   puts("Hey vincent, ta déja gouté les hamburger de big kaouna ?");
   lireClavier(chaine);
   printf("%s\n", chaine);

   return EXIT_SUCCESS;
}

void viderBuffer()
{
   int temp;
   
   while(temp != '\n' && temp != EOF)
      temp = getchar();
}

void lireClavier(char chaine[])
{
   char *positionEntree = NULL;
   
   if(fgets(chaine, TAILLE, stdin) != NULL)
   {
      positionEntree = strchr(chaine, '\n');
      if(positionEntree != NULL)
         positionEntree = '\0';
      else
         viderBuffer();
   }
   else
   {
      viderBuffer();
      exit(EXIT_FAILURE);
   }
}

Voila, pour ce dernier code, j'ai appellé deux fois la fonction viderBuffer(), la première, au cas ou la chaine entré est trop longue, dans ce cas l'appelle est justifié, la seconde dans le cas ou i ly aurais une erreur dans la saisie, dans ce cas on vide le buffer puis on quitte le programme.

Une dernière remarque, vous pouvez entrer des nombres avec fgerts de la même manière qu'avec scanf, seulement, ils seront considéré comme des chaines de caractères, donc n'essayez pas de faire des calculs avec ^^, il y a une autre fonction strtol(), qui permet de convertir des chaines de caractères en nombres, pour une saisie totalement sécurisé de vos programmes. Je ne connais pas encore les détails de cette fonction, mais en fonction de la demande, je peux apprendre à m'en servir et vous la décrire ici.

Voila c'est définitivement terminé pour la saisi sécurisé. Si vous etes arrivés jusqu'ici, que vous avez tous capter et que vous avez l'intention d'utiliser fgets par la suite plutôt que scanf, sa sera tout bénéf pour vous.

Bye
Revenir en haut Aller en bas
https://forum-du-groupe-h.forumactif.com
 
Un petit supplément sur les chaines de caractères.
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» petit délir, le pc qui chante en bip système

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Forum du groupe H :: Unité d'enseignement 1 :: Algorithmie-
Sauter vers: