Strings
Table de matières
La classe string
Définition
En C++, un string
est une collection de caractères. Pour les utiliser on doit
introduire la bibliothèque <string>
.
#include<string>
...
string s = "hello"
- Un string est un groupement de caractères entouré par ” “.
- On ne peut pas utiliser juste
' '
pour déclarer une chaine en C++."Ceci est une chaine"
'Ceci ne lest pas'
- Au niveau d’API, les chaines possèdent la même interface et fonctions que ceux de Java ou Python.
- La grande différence par rapport à ces langages est que les chaines de
caractères en C++ sont
mutables
. - Une autre différence, est que dans C++, on possède deux types de chaines de caractères.
Convertion
La méthode to_string
est très utile pour convertir un type de base à un string.
#include <iostream>
#include <string>
int main()
{
double f = 23.43;
double f2 = 1e-9;
double f3 = 1e40;
double f4 = 1e-40;
double f5 = 123456789;
std::string f_str = std::to_string(f);
std::string f_str2 = std::to_string(f2); // Note: returns "0.000000"
std::string f_str3 = std::to_string(f3); // Note: Does not return "1e+40".
std::string f_str4 = std::to_string(f4); // Note: returns "0.000000"
std::string f_str5 = std::to_string(f5);
std::cout << "std::cout: " << f << '\n'
<< "to_string: " << f_str << "\n\n"
<< "std::cout: " << f2 << '\n'
<< "to_string: " << f_str2 << "\n\n"
<< "std::cout: " << f3 << '\n'
<< "to_string: " << f_str3 << "\n\n"
<< "std::cout: " << f4 << '\n'
<< "to_string: " << f_str4 << "\n\n"
<< "std::cout: " << f5 << '\n'
<< "to_string: " << f_str5 << '\n';
}
si on veut controller le nombre de chiffres après la virgule où le poids de la
chaine, on utilise sprintf
Sa syntaxe générale est:
std::sprintf(buffer, "fmt", value);
fmt
: est le format voulue.value
: est la valeur convertie.buffer
: de type char * ( discuté après)
Aussi pour la conversion inverse (string– number), on utilise fonctions suivantes:
- stoi: convertir une chaine en entier.
- stol: convertir en long
- stof: convertir en float
- stod: convertir en double.
Tableau de caractères
Un string est construit de caractères de type char
. Ces caractères peuvent
être obtenus par indexation ( Vous devez être assez familiers avec ce
mécanisme).
string S = "Fear the Tree"
Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Character |
F | e | a | r | ' ' | t | h | e | ' ' | t | r | e | e |
Pour accéder à ces caractères, on utilise soit S[i]
soit la methode S.at(i)
char ch1 = S[3]; //'r'
char ch2 = S.at(2); //'a'
- Remarquer que les caractères sont entourés par
' '
et limité à un seul caractère. - La différence entre
[]
et la méthode.at()
est que l’opérateur[]
ne vérifie pas si vous êtes à l’extérieur des limites de votre chaine.
char ch1 = S[13]; //erreur de mémoire rien n'est signalé au compilateur
char ch2 = S.at(13); //Lance une exception out_of_range
- A ce stade, vous avez deux méthodes pour parcourir une chaine:
//Index based
for(size_t i = 0; i<chaine.size(); i++)
cout<<chaine[i];
cout<<endl;
//foreach
for(auto ch: chaine)
cout<<ch;
cout<<endl;
- Les caractères possèdent aussi un codage
ASCII
comme représenté dans la figure:
- Ceci implique qu’on peut réaliser des opérations mathématiques sur ces caractères.
Exercice: Réaliser un programme un programme qui encode la chaine “ATTACK AT DAWN” en utilisant le code de César par un k = 5.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string message = "ATTACK AT DAWN";
int key = 5;
string encoded = ""; //message encodé
for(auto ch: message)
{
//Encoder que les lettres
if( ch >= 'A' && ch<='Z')
{
//Formule d'encodage
char dis= ( ch - 'A' + key) % 26;
encoded += 'A' + dis;
}
else
encoded += ch;
}
cout<<encoded<<endl;
return 0;
}
Input: ATTACK AT DAWN
Output: FYYFHP FY IFBS
Méthode de string
Cette section présente l’essentiel des méthodes utilisées pour la manipulation des chaines.
cancatenation - Comparaison
- Comme
Java
etPython
, on peut concaténer deux chaine en utilisant l’opérateur + et +=.
string s1 = "Programmation"
string s2 = s1 + " CPP"; //s2 = Programmation CPP
s1 += " CPP"; //Ajouter CPP à S1
- Contrairement à
Java
on peut comparer directement des chaines en utilisant des opérateurs:
string s3 = "Zebra";
if ( s3 == "Tiger" )
cout<<"Different"<<endl;
if (s3 < "Tiger)
cout<<"inferieur<<endl;
- Contrairement à
Java
etPython
, les chaines en C++ sont mutables.
s3.append("Giraffe"); // s2 maintenant "ZebraGiraffe"
s3.erase(4,3); // effacer depuis 4, jusquà 7(4+3)
s3[5] = 'i'; // changer un seul caracères
s3[9] = 'e'; //Danger
- Contrairement à
Java
, C++ ne vérifie pas les bornes quand vous essayer d’accéder. Ainsi la grande philosophie:
Vous devez maitriser ce que vous faites!!!!
- Voici une liste de méthodes utiles de la classe string:
s.append(str)
: Ajouter une chaine à la fin.s.compare(str)
: comme Java, renvoie \([-1,0,1]\) selon le résultat de comparaison.s.erase(index, lenght)
: supprime les caractères de longueur lenght à partir de index.s.find(str)
: Recherche une chaine str, renvoienpos
en cas d’échec.s.insert(index, str)
: insert la chaine str à la position index.s.size()
: renvoie la longueur de la chaine.s.substr(start, length)
: renvoie la sous chaine de longueur lenght qui commence à la position start.
Bibliothèque Ctype
Une bibliothèque ctype
offre de fonctions de base pour la vérification des
caractères.
#include<ctype>
-
La bibliothèque offre de prédicats pour la vérification d’état d’une caractère.
- isalnum: vérifie si une caractère est alphanumérique.
- isalpha: vérifie si un caractère est alphabétique.
- islower: si minuscule.
- isupper: majuscule.
- isdigit: chiffre.
- isxdigit: chiffre hexadécimal.
- iscntrl: caractère de contrôle.
- isspace: espace.
- tolower: convertit en minuscule.
- toupper: convertit en majuscule.
- Exemple:
string mixed = "ab80c3d27"
cout<<"Chiffres en "<<mixed<<": "<<endl;
for(auto ch: mixed)
if( isdigit(ch) )
cout<<ch<<endl;
//Convertir en majuscule
string s = "ma chaine";
for(auto & ch: s)
ch = toupper(ch)
cout<<"Maintenant "<<s<<endl;
String Stream
La concaténation de chaine de caractères est très utile. Cependant, elle est
couteuse car on doit réallocer la mémoire en cas que la capacité de la
chaine qui recevante ne permet pas de stocker la chaine ajoutée. Une solution
plus adaptée à la manipulation des chaines dynémiques le string steam. Cette classe est déclarée dans la bibliothèque <sstream>
. Elle offre la possibilité de contruire des chaines avec les opérateurs de flux comme <<
et >>
. La liste des méthode à retenir est:
- operator«: pour acquérir des valeurs
- operator»: pour extraire des valeurs.
- str: obtenir la chaine de données.
- clear: supprimer le contenu.
Supposons qu’on possède les informations d’un étudiant ("Adil", "Fes", 23)
et
qu’on peut contruire un string pour cet étudiant de la forme name [state:
Fes] [age: 23]
. On peut réaliser cette opération par la concaténation, mais
une maniere plus simple est d’utiliser les flux.
Stduent S{"Adil", "Fes", 23};
//Construire un flux vid
stringstream SS;
//Envoyer les information de S à SS
ss<<S.name<<" [state: "<<S.state<<"] [age: "<<S.age<<"]";
//Obtenir la chaine de SS
cout<<ss.str()<<endl;
Inversement, on peut aussi utiliser les flux de chaines comme flux d’éntrée!!. Supposons qu’on possède une chaine de mots séparées par des espaces.
string str("Hello from the dark side");
Supposons qu’on veut obtenir tous ces mots? La solution simple ici est contruire
un flux sur str
et de contruire une boucle qui va lire tous ces mots.
// Flux de chaine construit sur str
stringstream SS(str);
//String pour lire les mots
string word;
//Boule de lecture
while( SS>>word)
{
cout<<word<<endl;
}
Un exemple est de convertir les nombre entre bases. Supposons par exemple qu’on veut obtenir la réprésentation du nombre 61 en héxadécimal.
int number = 61;
stringstream S;
//lire la valeur de number mais en hex
S<<hex<<number;
//Afficher cette valeur
cout<<S.str()<<endl;
Exercice
Ecrire un fonction qui reçoit une chaine de nombre séparées par virgule. La fonction doit afficher le contenu de ces nombres séparés par une nouvelle ligne.