En fait dans cette partie, comme le titre l'indique, je vais vous montrer comment récupérer une chaîne de caractère sans utiliser scanf(). Et comme je suis partageur, je vous montrerais aussi comment récupérer un seul caractère (ça vous le savez peut-être déjà mais on ne sais jamais

).
Récupérer une chaîne
Nous allons d'abord voir les saisies de chaînes. Alors quelles fonctions va t'on utiliser ?
Et bien la première vous la connaissez, c'est la fonction fgets().
Quoi ? Mais fgets() ne sert pas à lire une ligne d'un fichier ?
Si mais en C le flux d'entrée, stdin, est aussi considéré comme un fichier et il est ouvert automatiquement au début du programme. La fonction fgets() va permettre de lire ce flux et donc de récupérer les entrées clavier. Voici le prototype de cette fonction:
Code : C1 | char* fgets(char *s, int n, FILE *stream);
|
La fonction fgets() prends comme premier paramètre la chaîne dans laquelle elle va placer la saisie. Le deuxième paramètre est le nombre maximal de caractères (n-1 plus exactement) qui seront lus et le dernier paramètre est le flux à lire. Ici se sera stdin.
Mais comment connaît-on le nombre de bits à lire ? Tout simplement en utilisant sizeof qui permet de connaître le nombre de bits d'une variable. Voilà un exemple d'utilisation de la fonction fgets pour récupérer une chaîne:
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13 | #include <stdio.h>
#include <stdlib.h>
int main ( int argc, char* argv[] )
{
char chaine[20] = "";
printf("Entrez une chaine:\n");
fgets(chaine, sizeof(chaine), stdin);
printf("Chaine: %s.\n", chaine);
return 0;
}
|
Votre console affiche:
Code : Console | Entrez une chaine:
Je suis un zero
Chaine: Je suis un zero
.
Appuyez sur une touche pour continuer... |
Ici il y a deux choses à remarquer. Premièrement, la fonction fgets permet la saisie de chaînes contenant des espaces, ce que scanf() ne permet pas.
Et deuxièmement, il y a un saut de ligne à la fin de la chaîne. En effet, vous avez appuyé sur entrée pour saisir votre chaîne. Le caractère est donc à la fin de la chaîne.
Il y a un autre problème, on dit à la fonction fgets() de lire 19 caractères mais rien n'empêche l'utilisateur de rentrer 50 caractères. À ce-moment là un deuxième appel à la fonction fgets() récupérera la suite de l'entrée.
Il faut donc corriger ce problème.
Pour cela il faut utiliser une fonction, la fonction clean(). Elle n'est pas de moi et je l'ai tellement vue sur le forum que je suis incapable de vous donner son auteur.
Code : C 1
2
3
4
5
6
7
8
9
10
11 | void clean(const char *buffer, FILE *fp)
{
char *p = strchr(buffer,'\n');
if (p != NULL)
*p = 0;
else
{
int c;
while ((c = fgetc(fp)) != '\n' && c != EOF);
}
}
|
Je suppose que je dois vous expliquer cette fonction ?
Oui, bon d'accord. Alors cette fonction prend en paramètre la chaîne que vous avez récupérée avec fgets() et le flux qui est comme précédemment stdin. Cette fonction ne retourne rien.
D'abord, on cherche le caractère \n dans la chaîne à l'aide de la fonction strchr() (donc il faudra penser à inclure string.h). Si on trouve le \n, on le supprime de la chaîne et si on ne le trouve pas on vide le buffer avec une boucle while. Cette boucle ne s'arrête pas tant qu'elle lit un caractère différent de et que celui ci n'est pas le caractère de fin de flux ("Ctrl" + "Z" sur Windows ou "Ctrl" + "D" sur GNU/Linux).
Donc voici comment récupérer correctement une chaîne de caractère en C:
Code : C 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
29 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
void clean(const char *buffer, FILE *fp);
int main ( int argc, char* argv[] )
{
char chaine[20] = "";
printf("Entrez une chaine:\n");
fgets(chaine, sizeof(chaine), stdin);
clean(chaine, stdin);
printf("Chaine: %s.\n", chaine);
return 0;
}
void clean(const char *buffer, FILE *fp)
{
char *p = strchr(buffer,'\n');
if (p != NULL)
*p = 0;
else
{
int c;
while ((c = fgetc(fp)) != '\n' && c != EOF);
}
}
|
Et voici le résultat:
Code : Console | Entrez une chaine:
Je suis un zero
Chaine: Je suis un zero.
Appuyez sur une touche pour continuer... |
Vous pouvez enfin dire au revoir à scanf().
Récupérer un caractère
Alors pourquoi je n'utilise pas fgets() + clean() ? C'est simple, il existe une fonction permettant de ne récupérer qu'un seul caractère et non une chaîne. Cette fonction c'est getchar().
Bien sur ce n'est pas si simple. Si vous n'utilisez que getchar() vous pourrez rencontrer des problèmes. En effet, cette fonction prend le dernier caractère tapé par l'utilisateur. Donc voyez ce code:
Code : C1
2
3
4 | a = getchar();
printf("Vous avez tape la lettre %c\n", a);
b = getchar();
printf("Vous avez tape la lettre %c\n", b);
|
Avec ce code la console affiche:
Code : Console | d
Vous avez tape la lettre d
Vous avez tape la lettre
Appuyez sur une touche pour continuer... |
Vous voyez que votre programme ne vous demande pas de rentrer le deuxième caractère. C'est parce que lors du deuxième appel à la fonction getchar() celle ci récupère le caractère qui correspond à l'appui que vous avez fait sur la touche entrée après avoir tapé la lettre d. Cela se produit parce que le est toujours dans le "buffer".
Il faut donc enlever ce du buffer. Pour cela on fait juste une boucle comme ceci:
Code : C1 | while (getchar() != '\n');
|
Cela permet de vider le flux entrant. En effet, la boucle lit les caractères jusqu'à ce qu'elle ait lu le . Celui ci n'est donc plus dans le buffer. Essayez le code suivant:
Code : C1
2
3
4
5
6 | a = getchar();
while (getchar() != '\n');
printf("Vous avez tape la lettre %c\n", a);
b = getchar();
while (getchar() != '\n');
printf("Vous avez tape la lettre %c\n", b);
|
Vous pouvez voir que cette fois ci le programme vous demande bien les deux caractères:
Code : Console | d
Vous avez tape la lettre d
s
Vous avez tape la lettre s
Appuyez sur une touche pour continuer... |
Vous savez maintenant récupérer un caractère en C.