String ****** .. include:: ../BoutonGoogleTrad.rst La classe :cppterm:`std::string` est une classe de la bibliothèque standard du C++ permettant de représenter et de manipuler des chaînes de caractères. Deux manières de travailler =========================== Avec les caractères internationaux ---------------------------------- La classe :cpp:`std::string` du C++ ne sait pas manipuler les caractères internationaux. Ainsi, seulement les opérations simples vont fonctionner correctement dans ce contexte : - Affichage - Lecture / Ecriture - Concaténation avec l'oéprateur :cpp:`+` - Copie / Affectation - Egalité En revanche, certaines opérations comme retourner la longeur d'une chaîne donneront des résultats incorrects. En effet, cette fonction retourne la longueur en octets de la chaîne et malheureusement les caractères internationaux/accentués sont codés sur plusieurs octets. Avec les caractères ASCII ------------------------- L'ASCII est une norme créée dans les années 1960 pour standardiser l’échange de texte entre ordinateurs. Ce standard code chaque caractère sur 1 octet mais n'utilise que 7 bits, soit 128 caractères principalement adaptés à l’anglais. Ceci explique pourquoi il ne couvre pas correctement les caractères accentués ou les alphabets internationaux. Voici une présentation synthétique de la table ASCII : .. image:: ascii.png :scale: 30% :align: center .. warning:: Si vous limitez vos chaînes aux caractères :cpp:`ASCII`, l'ensemble des fonctions fournies par la classe :cpp:`string` fonctionneront correctement. Opérations de base ================== iostream -------- Cette librairie :cppterm:`iostream` propose un objet :cpp:`std::cout` permettant l'affichage à l'écran en utilisant l'opérateur :cpp:`<<`. La librairie :cpp:`` inclut aussi des constantes comme :cpp:`endl` pour effectuer un retour à la ligne. Voici un exemple : .. code-block:: cpp #include #include int main() { std::string s = "Hello"; std::cout << s << std::endl; } >> Hello .. note:: Vous pouvez supprimer les :cpp:`std::` en écrivant :cpp:`using namespace std;` en début de programme : .. code-block:: cpp #include #include using namespace std; int main() { string s = "Hello"; cout << s << endl; } Exemples -------- Voici quelques exemples pour découvrir les fonctions essentielles des :cpp:`string` et l'utilisation de l'opérateur :cpp:`<<` : .. code-block:: cpp #include #include using namespace std; int main() { // Creation / assignment string firstName = "John"; string lastName = "Smith"; // Display cout << "First name: " << firstName << " - " << "Last name: " << lastName << endl; // Concatenation string fullName = firstName + " " + lastName; // Copy string copy = fullName; // Equality test if (copy == fullName) cout << "The two strings are identical." << endl; // Input string city; cout << "Enter your city: "; getline(cin, city); cout << "You live in " << city << endl; return 0; } Fonctions ========= .. warning:: Vous devez savoir à quoi sert chacune de ces fonctions. Il n'est pas demandé de les connaître par coeur mais juste de savoir ce qu'elles font. .. csv-table:: Opérations sur les strings :header: "Type", "Exemple", "" :widths: 10, 10, 10 Affichage, :cpp:`cout << s1 << endl;` , Initialisation, :cpp:`string s1 = \"Exemple 1\";` , Initialisation, :cpp:`string s2(\"Exemple 2\");` , Initialisation, :cpp:`string t {\"Hello world\"};` , Conversion int->str, :cpp:`string s = to_string(42);` , Conversion str->int, :cpp:`stoi(s);`, Conversion str->double, :cpp:`stod(s);`, Conversion str->float, :cpp:`stof(s);`, Méthode, :cpp:`t.clear()`, Efface tous les caractères Méthode, :cpp:`t.erase(i٬nb)`, Retire :cpp:`nb` caractères à partir de l'index :cpp:`i` Méthode, :cpp:`t.insert(i٬\"1-\")`, Insère une chaîne dans la chaîne :cpp:`t` à la position :cpp:`i` Méthode, :cpp:`t.erase(index٬nb)`, Retire :cpp:`nb` caractères à la position :cpp:`i` Méthode, :cpp:`t.replace(index٬nb٬\"test\")`, Remplace les :cpp:`nb`caractères à la position :cpp:`i` Méthode, :cpp:`t.append(s1)`, Insère en fin Méthode const, :cpp:`t.length()`, Nombre de caractères Méthode const, :cpp:`t.find(\"Ex\")`, Retourne l'index de la première occurrence Méthode const, :cpp:`t.rfind(\"Ex\")`, Retourne l'index de la dernière occurrence Méthode const, :cpp:`t.substr(i٬nb)`, Retourne une sous-chaîne depuis l'index *i* Opérateur +, :cpp:`s1+\"@\"+s2`, Concaténation Opérateur +=, :cpp:`s1+= \"fin\"`, Insère en fin Opérateur [], :cpp:`s1[i]`, retour le i-ème caractère Opérateur <, :cpp:`s1 < s2`, Comparaison lexicographique Opérateur ==, :cpp:`s1 == s2`, Comparaison des caractères Test, :cpp:`t.empty()`, Indique si la chaîne est vide Test, :cpp:`t.starts_with(\"Ex\")`, Teste le début de la chaîne de caractères Test, :cpp:`t.ends_with(\"1\")`, Teste la fin de la chaîne de caractères .. quiz:: QuString2 :title: Opérations sur les string Les variables :cpp:`s1` et :cpp:`s2` représentent deux string initialisés avec \"BOB\" et \"EVA\". Pour chacune des expressions, donnez le résultat **SANS** guillemets : .. csv-table:: :header: Expression, Résultat :widths: 10, 10 :delim: ! :cpp:`s1 + \"_\" + s2` ! :quiz:`{"type":"FB","answer":"BOB_EVA"}` :cpp:`to_string(50)` ! :quiz:`{"type":"FB","answer":"50"}` :cpp:`s1.append(\"O\")` ! :quiz:`{"type":"FB","answer":"BOBO"}` :cpp:`s2.find(\"VA\")` ! :quiz:`{"type":"FB","answer":"1"}` :cpp:`s1[2]` ! :quiz:`{"type":"FB","answer":"B"}` :cpp:`s1 < s2` ! :quiz:`{"type":"FB","answer":"true"}` :cpp:`s2.ends_with(\"A\")` ! :quiz:`{"type":"FB","answer":"true"}` Si vous cherchez la documentation de la classe string, il faudra consulter celle de `la classe basic_string `_. Points techniques ================= Formatage des flottants ----------------------- La librairie ** fournit des fonctions permettant de contrôler l'affichage des nombres flottants : .. code-block:: cpp #include #include using namespace std; int main() { // indicates the number of digits after the decimal point. cout << setprecision(5) << 3.141519 << endl; // ==>> 3.1415 5 digits cout << setprecision(3) << 3.141519 << endl; // ==>> 3.14 3 digits // Padding Output cout << setfill('-'); cout << setw(5) << 25 << endl; // ---25 cout << setw(5) << 148; // --148 } Afficher vos objets ------------------- Il est possible de surcharger l'opérateur :cpp:`<<` pour que :cpp:`cout` puisse afficher de nouvelles classes : .. code-block:: cpp #include using namespace std; struct Point { int x, y; Point(int xx, int yy) { x = xx; y = yy; } }; ostream & operator << (ostream & stream, const Point & p) { stream << "(" << p.x << "," << p.y << ")"; return stream; } int main() { Point p(4,5); cout << p; } >> (4,5) Entrées/Sorties =============== Stream ------ La notion de :cppterm:`stream` en C++ correspond à un flux de données où l’on peut lire ou écrire. Il peut s’agir, par exemple, de la console, d’un fichier ou encore d’une chaîne de caractères servant d'input ou d'output buffer. La bibliothèque standard du C++ a homogénéiser la syntaxe permettant de gérer ces différents flux, ce qui permet par exempel d’utiliser le même opérateur :cpp:`<<` pour tous les streams de sortie. Output stream ------------- Dans cette catégorie, on trouve : * :cpp:`cout` : objet global associé au flux standard de sortie (l’écran) * :cpp:`ostringstream` : classe permettant d’écrire dans une chaîne de caractères * :cpp:`ofstream` : classe permettant d’écrire dans un fichier .. code-block:: cpp #include #include // string stream #include // file stream using namescape std; int main() { // output to console cout << "Hello !" // output to a string buffer ostringstream os; os << "Hello !" << endl; os << "How are you?"; cout << os.str(); // output to a file ofstream ofs("C:\\test\\output.txt"); ofs << "Hello !" << endl; ofs.close(); return 0; } Input stream ------------ La logique est identique pour les inputs streams : * :cpp:`cin` : objet global associé au flux standard d'entrée (le clavier) * :cpp:`ifstream` spécialisée dans la lecture des fichiers (input file stream) * :cpp:`istringstream` spécialisée dans la lecture des chaînes de caractères (input string stream) .. code-block:: cpp #include #include // string stream #include // file stream using namespace std; int main() { int a, b, c; // Input from keyboard cin >> a >> b >> c; cout << a << " " << b << " " << c << endl; // Input from a string istringstream iss("11 12 13"); iss >> a >> b >> c; cout << a << " " << b << " " << c << endl; // Input from a file ifstream ifs("C:\\test\\output.txt"); ifs >> a >> b >> c; cout << a << " " << b << " " << c << endl; ifs.close(); return 0; } .. note:: Depuis un fichier, ou depuis une :cpp:`string`, le caractère espace est utilisé comme séparateur entre les différentes informations. Dans les fonctions utiles, on peut citer : * :cpp:`getline(streamin,str)` : lit une ligne et la charge dans l'objet :cpp:`string str` * :cpp:`getline(streamin,str, \"#\")` : idem mais en utilisant le caractère :cpp:`#` comme séparateur