2.4- Manipulation de chaînes de caractères

Transcription

2.4- Manipulation de chaînes de caractères
2.4- Manipulation de chaînes de caractères
1- Les chaînes de caractères comme des tableaux de caractères
2- La classe string
1 Les chaînes de caractères comme des tableaux de caractères
Format des chaines
En C, il n'existe pas de type hors les types primitifs. A fortiori, il n'existe pas de classe string. La gestion des chaînes
de caractères passe alors par la manipulation de tableaux de char. Généralement une chaîne sera manipulée dans un tableau
de char surdimensionné par rapport à la talle de la chaîne qu'il contient. Le caractère '\0' indique la position de la fin de chaîne.
Par exemple, pour stocker le mot "Paris" dans un tableau de taille 10 :
char chaine[10];
chaine[0]='P';chaine[1]='a';chaine[2]='r';chaine[3]='i';chaine[4]='s';chaine[5]='\0';
char chaine2[]={'P','a','n','t','h','e','o','n','\0'};
Le caractère '\0' permet de savoir où se termine la chaîne et de manipuler les chaînes. On parle de caractère nul.
Récupération de chaînes par les entrées utilisateurs
En récupérant des données par cin, on constate que le caractère '\0' est introduit directement à la fin du mot :
std::cout << "Rentrer une chaine quelconque\n";
char chaineUtilisateur[100];
cin >> chaineUtilisateur;
char ch;
for(int i=0;i<100 && ch!='\0';i++)
{
ch=chaineUtilisateur[i];
std::cout << i << " " <<ch;
}
En rentrant la chaîne suivante :
Rentrer une chaine quelconque
Pronunciamento en Venezuela
0 P
1 r
2 o
3 n
4 u
10 e
11 n
12 t
13 o
14
5 n
6 c
7 i
8 a
9 m
On constate qu'effectivement, la boucle ne se poursuit pas sur l'ensemble du tableau. La seule raison en est que le caractère \0
a été rencontré. On constate qu'il a été introduit au niveau du caractère de césure qu'est l'espace. On verra au chapitre sur les
flux comment récupérer des chaînes incluant des espaces.
Fonctions des librairies cstring et cstdlib
Des fonctions de copie issues du C, mais qui restent valables en C++. La fonction strcpy permet de copie un tableau de char
vers un tableau de char. Cette fonction est comprise dans la librairie cstring :
char t[]="Les sanglots longs des violons";
char t2[100];
strcpy(t2,t);
Ici la chaîne du tableau t est copiée dans la seconde chaîne. Un problème se pose si le tableau source (t dans le code qui
précède) est plus grand que le tableau dans lequel on copie (t2 dans le code qui précède) : la copie se fera au delà de la limite
du tableau dans lequel on copie. La fonction strncpy est identique à strcpy, mais elle arrête la copie si le tableau source est plus
grand que le tableau cible. La fonction de copie permet également d'initialiser des chaînes :
char t[100];
strcpy(t,"Universite Paris II");
Dans la librairie cstring, il existe également une méthode de concaténation pour les string :
char t[200];
strcpy(t,"Universite Paris II");
strcat(t," localisee place du Pantheon");
strcat(t," a Paris");
D'autres fonctionnalités sur les chaînes comme tableaux de char sont fournies par les librairies cstdlib et cstring : ce sont des
fonctions de recherche au sein des chaînes, des fonctions d'extraction de caractères, des fonctions de conversion de chaînes
vers des variables de type double ou de type int. Ces fonctions ne sont pas évoquées ici : les chaînes dans leur version C n'ont
été évoquées qu'à titre d'information et parce que ce type de technique connaît une certaine survivance. Néanmoins, on
préférera largement gérer les string en utilisant la classe string fournie en CPP.
Vers la classe string
La manipulation des tableaux de char, seule méthode possible pour la manipulation de chaine en C, s'avère conduire à
des erreurs et s'avère consommer beaucoup de ressources machine. Par ailleurs, cette gestion des chaines n'est pas orientée
objet. C++ implémente donc une solution orientée objet au travers de la classe string.
La manipulation des char* ou char[] représentait une grosse perte de temps pour le programmeur en C. L'introduction
de la classe string en C++ résout beaucoup de difficultés.
2 La classe string
C++ introduit la classe string qui est déclarée dans la librairie <string>. La manière dont les string sont implémentées
en mémoire n'est pas traitée par la norme C++. La manipulation des string s'avère assez souple.
Création et initialisation de chaînes
Pour créer une chaîne vide :
string str;
Pour créer une chaîne avec un contenu :
string str2("Langage C++");
Pour créer une chaîne avec l'opérateur = :
string str3="Langage C++";
Initialiser une chaîne à partir d'une chaîne :
string str3="Langage C++";
string str4(str3);
Pour créer une chaîne à partir des 12 premiers caractères d'une chaîne :
#include <iostream>
using namespace std;
int main(){
string str("Les sanglots longs des violons");
string st(str,0,12);
std::cout << "\"" << st << "\"\n";
}
Ce code affiche "Les sanglots" : soit les caractères indiciés de 0 à 11 (12 caractères).
D'autres méthodes sont possibles pour initialiser :
#include <iostream>
using namespace std;
int main(){
string str("Les sanglots longs des violons");
string st(str.substr(4,12));
std::cout << "\"" << st << "\"\n";
}
On initialise a partir d'une sous-chaîne. Pour récupérer une string extraite à partir d'une string, on utilise la méthode
substr(int,int) associée au string. Elle prend en paramètre deux entiers. Le premier est le numéro du caractère de début
d'extraction et le second est le nombre de caractères extraits.
Opérateurs sur les string
Plusieurs opérateurs existent dont tous ne sont pas évoqués ici.
+ est l'opérateur de concaténation.
string str("Les sanglots longs des violons ");
string str2("de l'automne blessent mon coeur");
int i=5;
string str3=str+str2;
std::cout << str3;
Ici, la chaine suivante est affichée :
Les sanglots longs des violons de l'automne blessent mon coeur
Comparaison des string
Les opérateurs ==, !=, >, <, >=, <= ont été surchagés pour comparer des string. La comparaison est alors lexicographique :
ème
str1<str2 est vrai si les n premiers caractères de str et str2 sont identiques, mais que le n+1
n+1
ème
caractère de str précède le
caractère de str2.
Quelques méthodes de string
On a déjà noté qu'il existe une fonction d'extraction de sous-chaînes : substring. Il existe également une fonction de
remplacement de caractères au sein d'une chaîne : la fonction replace. Elle a plusieurs versions surchargées. La plus utilisée
prend trois paramètres : un numéro de départ, le nombre de caractères à éliminer de la chaîne courante et la chaîne de
remplacement.
string str("Les sanglots longs des violons ");
string str2("de l'automne blessent mon coeur");
std::cout << str.replace(str.size()-1,0," "+str2) << "\n";
Ici, on remplace dans str, à partir du dernier caractère (str.size() est la taille de la chaîne str).
Il est également possible de localiser des sous-chaînes au sein des string. Il existe une série de fonctions de recherche. On se
contente ici de donner la fonction find() : elle cherche un caractère ou une série de caractères au sein d'une chaîne et renvoie la
première occurrence trouvée dans la chaîne.
On peut utiliser find() avec une chaîne :
string str("Les sanglots longs des violons de l'automne blessent mon coeur");
int n=str.find("sanglots");
std::cout << n << "\n";
Cette exécution affiche 4.
On peut aussi utiliser la fonction avec deux paramètres : une chaîne à rechercher, un numéro de caractère de début de
recherche. find() renverra alors le numéro de la première occurrence de la chaîne à partir du numéro de recherche. Il est
possible de concevoir une fonction renvoyant toutes les occurrences d'une sous-chaîne à partir de là :
#include <iostream>
#include <string>
using namespace std;
int main(){
string str("Les sanglots longs des violons de l'automne blessent mon coeur");
int indiceFin=str.size();
int indiceDebut=0;
string aChercher("es");
while(indiceDebut<indiceFin)
{
int indice=str.find(aChercher,indiceDebut);
std::cout << indiceDebut << " " << indice << " " << indiceFin << "\n";
if(indiceDebut<=indice && indice <=indiceFin)
{
indiceDebut=indice+1;
std::cout << "Occurrence de \""+aChercher+"\" au caractere numero "<< indice << "\n";
}
else
indiceDebut=indiceFin+1;
}
}
Manipulation de string comme d'un tableau
La fonction size(); de la classe string permet de récupérer la taille d'une chaîne. Il est possible de manipuler les chaînes comme
des tableaux en utilisant size() et l'opérateur [], ou l'opérateur at :
#include <iostream>
#include <string>
using namespace std;
int main(){
string str("Les sanglots longs des violons de l'automne blessent mon coeur");
for(int i=0;i<str.size();i++)
std::cout << str.at(i) << " " << str[i] << "\n";
}
Les chemins de fichier
A noter la manière d'écrire les chemins de fichiers. De la même manière qu'il faut introduire les sauts de ligne en écrivant '\n'
dans une chaîne, introduire des tabulations en introduisant '\t' dans une chaîne, on introduit le caractère \ en mettant '\\' dans
une chaîne :
string vers1("Freres humains qui apres nous vivez\n");
string vers2("N'ayez les coeurs contre nous endurciz,\n");
string auteur("\t\tVillon\n");
string str("c:\\CPP\\EcoExp\\simulation.txt");
std::cout << vers1+vers2+auteur+str;