Série 12, exercice 3

Série 12, exercice 3

par Rachel Tranchida,
Number of replies: 2

Bonjour,

Je voulais faire l'exercice 3 de la série 12, mais il nous est demandé d'utiliser la fonction get(char) pour lire le fichier caractère par caractère, et je ne comprends pas bien son fonctionnement (quel caractère en argument, qu'est-ce qu'elle retourne, comment avancer dans le fichier de cette façon). Il y a bien un lien vers la mini-référence, mais je ne vois que les fonctions "cin.get(char c)" et "cout.get(char c)" qui sont semblables. Est-ce que c'est ce que je dois utiliser ? Y en a t'il une autre ? Comment l'utiliser ? Où préciser que l'on veut prendre les caractères dans notre flot d'entrée ? 


Merci d'avance, meilleures salutations.

In reply to Rachel Tranchida

Re: Série 12, exercice 3

par Samuel Ernst,

Bonjour,

Oui en effet, il s'agit bien de méthode similaire à celle de la mini-ref : cin.get(char). (En outre cout.get(char) n'exsite pas, je suppose que vous vouliez parler de cout.put(char))

Cette fonction n'est en fait pas propre à cin mais à tout flux d'entrée, en particulier ifstream pour la lecture de fichiers. Son prototype est le suivant :

istream& get(char& c);


La variable de type char qu'elle prend en paramètre est la variable qui sera remplie avec le prochain caractère du flux. D'où le passage par référence, un passage par copie n'aurait pas permis ce type de retour. La valeur de retour est de type istream&, je passerai les détails du pourquoi et du comment car c'est quelque chose que vous verrez plus en profondeur au deuxième semestre avec la programmation orientée objet. Pour le moment il faut comprendre que la fonction retourne une référence vers le flux d'entrée qui est utilisé. Dans le cas de cin.get(char) la valeur de retour est cin, dans le cas d'un flux vers un fichier c'est ce même flux qui est retourné :

ifstream fichier;
char lettre;
// ...
fichier.get(lettre); // retourne une référence sur fichier et change la valeur de lettre


(La fonction est appelée sur le flux donné avant le point de : ".get". Cette syntaxe fera plus de sens au deuxième semestre lorsque vous verrez le concept de méthodes. Pour le moment il faut le voir comme un appel de la fonction get() sur la variable fichier. Tout comme avec les vector<> on avait vec.size() qui est un appel de la fonction size() sur la variable vec.)

Ceci peut sembler un peu étrange, pourquoi ne pas directement retourner le char ? L'une des raisons c'est de pouvoir profiter du fait que si l'on essaie d'utiliser une variable de type flux à la place d'un bool, par exemple dans un test, alors c'est la validité du flux qui est testée. On peut alors imaginer réagir à la récupération du caractère seulement si la récupération c'est bien passée :

if(fichier.get(lettre))
{
    // Ici on a bien la prochaine lettre
}
else
{
    // Un problème est survenu, il faut qu'on réagisse convenablement !
}


En plus de récupérer le prochain caractère du flux, la fonction get(...) passe au caractère suivant. Cela signifie qu'on peut récupérer plusieurs caractères successifs en faisant plusieurs appels à la même fonction sur le même flux. Lorsque on atteint la fin du flux (ou ici la fin du fichier) un caractère spéciale est récupérer et le flux se "bloque" dans un état spécial EOF pour End Of Stream. Cet état peut être testé avec .eof(), mais pas seulement, il peut également être testé comme les autres états d'invalidité du flux directement en utilisant le flux comme un bool. Il est alors possible de boucler sur tous les caractères d'un fichier jusque a atteindre la fin (ou une erreur) avec le code suivant :

while(fichier.get(lettre))
{
    // Ici on lit une lettre ...
}
// On a finit de lire le fichier !


J'espère avoir convenablement répondu a toute vos questions. Si un point n'es pas claire ou si vous désirez un approfondissement n'hésitez pas à demander.

Bonne soirée