Table de matières

  1. C++ Strings et C srings
  2. Caractères
  3. Méthodes
  4. Bibliothèque <ctype>
  5. Class stringstream

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:
Le codage de César est une méthode de cryptographie formée en translatant chaque lettre à droit ou gauche par un paramètre $k$. Par exemple pour un codage $+3$, la lettre 'A' sera codée par 'D' et 'B' par 'E'. A la fin les lettre devient au début. Par exemple la lettre 'X' sera codée par 'A', 'Y' par 'B' et 'Z' par 'C'. César a confirmé qu'il as utilisé ce schéma pour envoyer ces plans d'action de guère pour ces généraux.
  • 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 et Python, 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 et Python, 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, renvoie npos 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.