This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
in204:tds:sujets:td5:part2 [2019/10/08 19:00] bmonsuez [Question n°1.2] |
in204:tds:sujets:td5:part2 [2022/11/18 10:48] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Partie II – Manipulation des flux====== | ====== Partie II – Manipulation des flux====== | ||
+ | |||
+ | [[in204:tds:sujets:td5|TD5]] | ||
===== Question n°1 ==== | ===== Question n°1 ==== | ||
Line 22: | Line 24: | ||
L'opérateur prend comme premier argument un flux en lecture [[https://en.cppreference.com/w/cpp/io/basic_istream|''std::basic_istream<charT, charTraits>&'']] et comme second argument un nombre ''Complex''. Comme le nombre va pas être modifié, il est nécessaire de passer une référence à l'objet qui va recevoir la valeur lue du flux, d'où la signature précédente. Comme nous souhaitons associer les opérations d'écriture sur le flux, l'opérateur ''>>'' retourne une référence sur le flux duquel nous venons de lire la donnée. | L'opérateur prend comme premier argument un flux en lecture [[https://en.cppreference.com/w/cpp/io/basic_istream|''std::basic_istream<charT, charTraits>&'']] et comme second argument un nombre ''Complex''. Comme le nombre va pas être modifié, il est nécessaire de passer une référence à l'objet qui va recevoir la valeur lue du flux, d'où la signature précédente. Comme nous souhaitons associer les opérations d'écriture sur le flux, l'opérateur ''>>'' retourne une référence sur le flux duquel nous venons de lire la donnée. | ||
- | |||
- | |||
- | |||
- | |||
- | |||
==== Question n°1.1 ==== | ==== Question n°1.1 ==== | ||
Line 38: | Line 35: | ||
Testez cette opération. | Testez cette opération. | ||
+ | |||
+ | <hidden Correction> | ||
+ | |||
+ | L'opérateur ''std::basic_ostream<charT, traits>& operator << (std::basic_ostream<charT, traits>&, const Complex&)'' doit être défini en dehors de la classe ''Complex'' puisqu'il prend comme premier argument un argument de type différent de ''Complex''. Cependant, cet opérateur doit pouvoir accéder aux champs internes de la classe. | ||
+ | |||
+ | Nous avons deux possibilités, soit nous décidons d'avoir une méthode interne d'affichage : | ||
+ | |||
+ | <code cpp> | ||
+ | class Complex | ||
+ | { | ||
+ | ... | ||
+ | public: | ||
+ | ... | ||
+ | template<class charT, class traits> | ||
+ | void print(const std::basic_ostream<charT, traits>, & aStream) | ||
+ | { | ||
+ | aStream << mRealPart; | ||
+ | aStream << "+ i "; | ||
+ | aStream << mImaginaryPart; | ||
+ | } | ||
+ | ... | ||
+ | }; | ||
+ | |||
+ | template<class charT, class traits> | ||
+ | std::basic_ostream<charT, traits>& operator<charT, traits> << (std::basic_ostream<charT, traits>& aStream, const Complex& aNumber) | ||
+ | { | ||
+ | aNumber.print(aStream); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | L'autre possibilité consiste à déclarer l'opérateur ''std::basic_ostream<charT, traits>& operator << (std::basic_ostream<charT, traits>&, const Complex&)'' comme étant "ami" de la classe, ce qui lui donne accès aux méthodes et champs privés et protégés de la classe. | ||
+ | |||
+ | <code cpp> | ||
+ | class Complex | ||
+ | { | ||
+ | ... | ||
+ | public: | ||
+ | ... | ||
+ | template<class charT, class traits> | ||
+ | friend std::basic_ostream<charT, traits>& operator<charT, traits> << (std::basic_ostream<charT, traits>& aStream, const Complex& aNumber) | ||
+ | { | ||
+ | } | ||
+ | ... | ||
+ | }; | ||
+ | |||
+ | template<class charT, class traits> | ||
+ | std::basic_ostream<charT, traits>& operator<charT, traits> << (std::basic_ostream<charT, traits>& aStream, const Complex& aNumber) | ||
+ | { | ||
+ | aStream << aNumber.mRealPart; | ||
+ | aStream << "+ i "; | ||
+ | aStream << aNumber.mImaginaryPart; | ||
+ | return aStream; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Il serait cependant préférable de pouvoir effectuer un affichage minimaliste des nombres complexes. Ainsi, nous nous contentons d'afficher la partie réelle si la partie imaginaire et nulle ou la seule partie imaginaire si la partie réelle est nulle. Cet affichage plus proche de l'affiche courant peut être fourni pas le code suivant : | ||
+ | |||
+ | <code cpp> | ||
+ | template<class charT, class charTraits> | ||
+ | std::basic_ostream<charT>& operator <<( | ||
+ | std::basic_ostream<charT, charTraits>& aStream, | ||
+ | const Complex& aValue) | ||
+ | { | ||
+ | if(aValue.mRealPart != 0 && | ||
+ | aValue.mImaginaryPart != 0) | ||
+ | aStream << aValue.mRealPart << "+" << aValue.mImaginaryPart << "i"; | ||
+ | else if(aValue.mImaginaryPart != 0) | ||
+ | aStream << aValue.mImaginaryPart << "i"; | ||
+ | else | ||
+ | aStream << aValue.mRealPart; | ||
+ | } | ||
+ | </code> | ||
+ | </hidden> | ||
==== Question n°1.2 ==== | ==== Question n°1.2 ==== | ||
Line 44: | Line 114: | ||
<code cpp> | <code cpp> | ||
- | x + i y | + | x + i y |
x - i y | x - i y | ||
i y | i y | ||
Line 50: | Line 120: | ||
x | x | ||
</code> | </code> | ||
+ | |||
Définissez une opération de lecture d’un flux effectuant cette lecture d’un objet de type ''Complex''. | Définissez une opération de lecture d’un flux effectuant cette lecture d’un objet de type ''Complex''. | ||
Pour ce faire, il va falloir déterminer le format au fur et à mesure de la lecture des éléments à partir du flux. | Pour ce faire, il va falloir déterminer le format au fur et à mesure de la lecture des éléments à partir du flux. | ||
+ | |||
+ | ---- | ||
Vous pouvez vous reporter à la documentation de [[https://en.cppreference.com/w/cpp/io/basic_istream|''std::basic_istream<charT, charTraits>&'']] qui vous indiquera les fonctions qu’offrent la classe et qui vous seront utiles pour analyser le flux en entrée. | Vous pouvez vous reporter à la documentation de [[https://en.cppreference.com/w/cpp/io/basic_istream|''std::basic_istream<charT, charTraits>&'']] qui vous indiquera les fonctions qu’offrent la classe et qui vous seront utiles pour analyser le flux en entrée. | ||
+ | |||
+ | Pour analyser, il faut tout d'abord tester le premier caractère qui n'est pas un espace. En fonction de cette valeur, nous pouvons soit : | ||
+ | * être en présence d'un nombre, | ||
+ | * être en présence d'un signe ''+'' ou ''-'', | ||
+ | * être en présence d'un caractère ''i'' ou ''I'' | ||
+ | |||
+ | Pour chacun des cas, vous devez avancer dans le flux pour déterminer si la suite du format est compatible avec la lecture des formats précédemment définis. Cependant, si vous constatez que vous avez fait une mauvaise supposition, il sera nécessaire de restaurer la position dans le flux au niveau du premier caractère qui ne fait pas partie de la séquence. | ||
+ | |||
+ | Par exemple, si nous avons ''3 + 2'' comme expression, nous allons avoir l'analyse suivante : | ||
+ | - Analyse de ''3'' => partie réelle est ''3'' | ||
+ | - Détection du signe => peut-être suivi d'une partie imaginaire | ||
+ | - Analyse de ''2'', la partie imaginaire peut-être ''2'', | ||
+ | - Absence de 'i' ou 'I' suivant l'item ''2'', => absence de partie imaginaire, nous devons repositionner le pointeur de flux au niveau du premier caractère suivant le ''3''. | ||
+ | |||
+ | Typiquement les fonctions suivantes : | ||
+ | * [[https://en.cppreference.com/w/cpp/io/basic_istream/get|''get'']], [[https://en.cppreference.com/w/cpp/io/basic_istream/peek|''peek'']] vous permettent d'avancer dans la lecture des caractères, | ||
+ | * [[https://en.cppreference.com/w/cpp/io/basic_istream/unget|''unget'']] vous permettent de remettre un caractère que vous venez d'extraire dans le flux, | ||
+ | * [[https://en.cppreference.com/w/cpp/io/basic_istream/tellg|''tellg'']] et [[https://en.cppreference.com/w/cpp/io/basic_istream/seekg|''seekg'']] vous permettent d'accéder à la position courant et de revenir à une position antérieur. | ||
+ | pourront vous être utiles. | ||
+ | |||
+ | ---- | ||
+ | |||
+ | <hidden Correction> | ||
+ | |||
+ | Nous començons à nous intéresser à l'affichage selon le format: | ||
+ | |||
+ | </hidden> | ||
==== Question n°1.3 (En dehors du cours !) ==== | ==== Question n°1.3 (En dehors du cours !) ==== |