Lecture et écriture dans des chaînes de caractères#
Nous avons vu comment lire et écrire facilement des valeurs de types divers (entiers, flottants) dans un fichier texte. Sous le capot cela a requis des opérations de natures différentes :
interactions avec le système pour lire et écrire du texte dans un fichier
conversions de valeurs en texte et réciproquement
Ne pourrait-on pas utiliser ce deuxième point pour lire et écrire des valeurs dans des chaînes de caractères? Après tout, elles contiennent du texte elles aussi! Allons-y.
Au préalable, nous aurons besoin de la bibliothèque suivante :
#include <sstream>
using namespace std;
Lecture depuis une chaîne de caractères#
Exemple#
La chaîne de caractère suivante contient – sous forme de texte – plusieurs nombres :
string s = "1 2 4 8 16";
Comment extraire ces nombres de s
?
On souhaiterait extraire ces nombres en les convertissant en entiers.
Pour cela on créé un flux de type istringstream
(pour flux entrant
depuis une chaîne de caractères) rattaché à s
:
istringstream flux = istringstream(s)
Maintenant il est possible de lire le premier nombre, en procédant comme s’il était dans un fichier :
int i;
flux >> i;
i
Lorsque l’on effectue de nouvelles lectures, les nombres suivants sont lus un à un :
flux >> i;
i
flux >> i;
i
flux >> i;
i
L’exemple suivant illustre que l’on peut lire successivement des valeurs de types mixtes, qu’un nombre quelconque d’espaces sert de séparateur, et que l’on peut enchaîner ces lectures :
string s = "truc 33 bidule 2.5 reste"
istringstream flux = istringstream(s);
string a, b;
int i;
float f;
flux >> a >> i >> b >> f;
a
b
i
f
Syntaxe et sémantique#
Syntaxe
istringstream flux = istringstream(s);
flux >> variable1;
flux >> variable2;
...
Sémantique
Affecte aux variables variable1
, variable2
, … les valeurs lues
successivement depuis la chaîne de caractères s
, en tenant compte de
leurs types respectifs.
Écriture dans une chaîne de caractères#
Réciproquement, on peut souhaiter écrire le contenu de variables non pas directement à l’écran ou dans un fichier mais dans une chaîne de caractères. Le principe sera le même que pour une lecture.
Exemple#
On commence par définir un flux de type ostringstream
(pour flux
sortant vers une chaîne de caractères) :
ostringstream flux;
Nous pouvons maintenant écrire dans ce flux :
flux << 3.53 << " coucou " << 1 << endl;
flux << 42 << endl;
et enfin extraire la chaîne de caractère produite :
string s = flux.str();
s
Syntaxe et sémantique#
Syntaxe
ostringstream flux;
flux << variable1;
flux << variable2;
string s = flux.str()
Sémantique
Construit une chaîne de caractères s
en écrivant successivement le
contenu des variables variable1
, variable2
, … en tenant compte
de leurs types respectifs.
Application typique : séparation calcul et entrées sorties#
Ce que nous venons de voir sera très utile pour séparer proprement ce qui relève du calcul et ce qui relève des entrées-sorties. Supposons par exemple que nous souhaitions afficher joliment une entrée d’un annuaire :
using namespace std;
#include <iostream>
#include <sstream>
void afficheEntreeAnnuaire(string nom, string prenom, string tel) {
cout << "Nom: " << nom
<< ", Prénom: " << prenom
<< ", Téléphone: " << tel;
}
afficheEntreeAnnuaire("Lovelace", "Ada", "07 23 23 23 23")
Questions
Comment réutiliser cette fonction pour écrire le texte non pas à l’écran mais dans un fichier?
Comment tester cette fonction?
Cela est rendu difficile par le mélange de deux actions de natures différentes dans une seule fonction :
Construire le texte représentant l’entrée dans l’annuaire.
Afficher ce texte à l’écran.
Il faut donc séparer ces deux actions. L’écriture dans une chaîne va nous aider à le faire.
La fonction suivante se concentre sur la construction du texte représentant l’entrée dans l’annuaire :
string formateEntreeAnnuaire(string nom, string prenom, string tel) {
ostringstream flux;
flux << "Nom: " << nom
<< ", Prénom: " << prenom
<< ", Téléphone: " << tel;
return flux.str();
}
Le texte produit est renvoyé par la fonction au lieu d’être affiché. Nous pouvons donc maintenant :
l’affecter à une variable :
string s = formateEntreeAnnuaire("Lovelace", "Ada", "07 23 23 23 23")
l’afficher :
cout << s << endl;
calculer avec :
"- " + s
ou nous en servir pour toute autre opération, comme l’écrire dans un fichier.
De plus, nous pouvons maintenant aisément tester notre fonction :
CHECK( formateEntreeAnnuaire("Lovelace", "Ada", "07 23 23 23 23")
== "Nom: Lovelace, Prénom: Ada, Téléphone: 07 23 23 23 23" );
Résumé#
Dans cette feuille:
nous avons vu comment lire et écrire des données de types divers dans des chaînes de caractères.
Nous l’avons appliqué pour mieux séparer fonctions qui calculent et fonctions d’entrées-sorties.
Enfin nous avons noté que, grâce au concept de flux, on peut utiliser la même syntaxe que pour lire et écrire dans un fichier ou pour interagir avec l’utilisateur.