Accueil > Programmation Cocoa > Gestion des chaînes de caractères sous Cocoa - Partie 2

Gestion des chaînes de caractères sous Cocoa - Partie 2

Par Mike Beam, le 13/07/2001

traduit par Thierry, le 15/05/2002

Cet article est la suite de celui consacré aux chaînes de caractères Cocoa. Dans l’article précédent, nous avons abordé les principes de base de la manipulation des chaînes tels que vous les auriez appris avec n’importe quel langage ou environnement.

Nous avons commencé par les étapes essentielles à la création de chaînes avec la grande variété de méthodes fournies par la classe NSString, puis nous avons appris comment utiliser ces chaînes. Nous en avons aussi un peu plus appris sur la POO (Programmation Orientée Objet) avec les “cluster” (grappes de classes), et un peu plus sur les entrées/sorties de chaînes dans les fichiers. Additionnellement, pas mal de temps a été consacré aux méthodes de comparaisons, de recherches et d’extractions de sous-chaînes.

Aujourd’hui, je veux poursuivre ce cours en vous parlant des outils NSString de manipulation et de la sous-classe NSMutableString de la classe NSString, qui nous permet de créer des chaînes dont le contenu peut être édité après leur création - quelque chose d’impossible avec la classe NSString toute seule. Je conclurai enfin cet article avec quelques friandises diverses relatives aux chaînes. Ceci étant dit commençons !

Manipuler des chemins d’accès

Dans l’article précédent, je vous ai montré comment nous pouvions écrire des chaînes dans un fichier texte. Dans ces exemples, nous avons représenté l’emplacement du fichier (chemin d’accès) sous forme de chaîne. Ce sera toujours le cas quand nous travaillerons avec des fichiers sauf que le chemin d’accès sera des chaînes d’objets NSString.

La représentation sous forme de chaîne des emplacements et des chemins d’accès de fichiers est standard sous Cocoa. La classe NSString fournit un ensemble de méthodes qui nous permettent de manipuler les chaînes de chemin d’accès. Ces méthodes nous permettent de faire des choses telles que remplacer le caractère tilde “~” d’un chemin d’accès par un chemin absolu, de résoudre des liens symboliques, d’extraire des composants du chemin d’accès vers une nouvelle chaîne et, de manipuler les extensions de fichiers.

Désormais nous savons tous que Mac OS X est basé sur UNIX (ô combien j’aimerais m’étendre sur le succès de cette migration d’Apple !), et de ce fait, les répertoires et les fichiers sont organisés et manipulés à la mode Unix. Il y a plusieurs choses que vous devez savoir à ce propos et qui sont différentes du mode normal utilisé par le Macintosh. Je me doute que beaucoup d’entre vous sont aguerris à ces principes mais il n’est jamais mauvais d’aborder quelques principes fondamentaux, donc soyez tolérants avec moi.

A la mode Unix, le chemin d’accès au répertoire d’accueil d’un utilisateur (”Home Directory“) est raccourci avec un tilde (”~“). C’est une abréviation pratique pour se balader dans le système de fichiers. Par exemple, mon répertoire d’accueil est sur mon iBook vert citron : /Users/mike/ de manière étendue, ou simplement ~ de manière raccourcie. Toutefois, un tilde, contenu dans un chemin d’accès, ne sera jamais reconnu comme un chemin valide, nous devrons donc le transformer en utilisant la méthode - stringByExpandingTildeInPath.

Dans l’exemple suivant :

NSString *shortPath = @”~/textFile.txt”;
NSString *absolutePath = [shortPath stringByExpandingTildeInPath];

la méthode - stringByExpandingTildeInPath retournera une chaîne qui représentera le chemin d’accès étendu (absolu) au fichier textFile.txt, dans laquelle le tilde aura été remplacé par le chemin d’accès au répertoire d’accueil de l’utilisateur en cours.

Le nouveau chemin est donc maintenant /Users/mike/textFile.txt. Nous pouvons aussi accomplir l’inverse, c’est à dire remplacer le chemin d’accès au répertoire d’accueil de l’utilisateur par un tilde en utilisant la méthode -stringByAbbreviatingWithTildeInPath:

NSString *path = [absolutePath stringByAbbreviatingWithTildeInPath];

qui donnerait la valeur ~/textFile.txt au chemin d’accès. Notez que dans toutes ces méthodes, le premier mot est “string“, ce qui veut dire qu’une chaîne est reçue par le récepteur du message du type “string“. Cette syntaxe est commune à toutes les programme-cadres Cocoa et nous la rencontrerons aussi avec les tableaux, les nombres, les dictionnaires et ainsi de suite. Les noms de méthodes Cocoa sont conçus pour être le moins ambigus possible.

Les extensions de fichiers sont aussi très répandues sous Unix (trop au goùt de beaucoup d’utilisateurs Mac). Une extension est le suffixe, composé de une, deux, trois ou quatre lettres, qui est placé après le nom d’un fichier (et après le “.”). Nous pouvons extraire l’extension d’un fichier pour en faire un objet de type chaîne de caractères en invoquant la méthode - pathExtension sur certaines chaînes de chemin d’accès afin d’obtenir l’extension du chemin d’accès, sans le point.

NSString *path = @”~/textFile.txt”;
NSString *pathExtension = [path pathExtension];

La chaîne pathExtension serait “txt” dans cet exemple. Le point est enlevé. S’il n’y a aucun point qui indique une extension de chemin d’accès, une chaîne vide est retournée. S’il n’y a aucun fichier, une chaîne vide est aussi retournée.

Naturellement, il y a une méthode pour faire l’inverse, c’est à dire, ajouter une extension là où il y en avait une auparavant. Cela s’accomplit en utilisant la méthode - ByAppendingPathExtension :. Si nous avions une chaîne contenant le chemin d’accès suivant /Users/mike/textFile, nous pourrions y ajouter l’extension de chemin “.txt” en faisant comme suit :

NSString *path = @”Users/mike/textFile”;
path = [path stringByAppendingPathExtension:@"txt"];

Le chemin deviendrait alors /Users/mike/textFile.txt. Notez que dans cet exemple, nous avons écrasé l’ancien chemin d’accès, par le nouveau chemin retourné, dans la variable path.

Si nous voulions enlever l’extension de manière à n’avoir que le chemin et le nom du fichier, nous utiliserions la méthode - stringByDeletingPathExtension. Avec notre chemin d’accès originel /Users/mike/textFile.txt :

path = [path stringByDeletingPathExtension];

le path deviendrait alors /Users/mike/textFile. La méthode retourne la chaîne originelle sans l’extension (et sans le point précédent l’extension).

Manipuler des chemins d’accès (suite)

Une autre famille d’outils NSString de manipulation de chemins d’accès est celle qui nous permet de manipuler les composants d’un chemin d’accès, les noms individuels des répertoires et du fichier lui même. La première de ces méthodes est -pathComponents. Elle semble assez facile. Ce qu’elle fait est explorer une chaîne représentant un chemin d’accès afin d’en extraire les sous-chaînes séparées par les barres (slash) et les mettre dans un objet NSArray. Nous n’avons pas encore parlé des NSArray, mais ce n’est rien de plus que des tableaux standard dans le style Cocoa.

Ainsi, si nous avons le chemin d’accès suivant :

NSString *thisColumn = @”/Users/mike/Documents/Cocoa_Column/Column8.doc”

(je l’admets, j’affectionne assez Word.) -pathComponents le séparerait en plusieurs éléments et formerait un tableau comme suit :

NSArray *theComponents = [thisColumn pathComponents];

Le tableau qui en résulterait ressemblerait à ceci :

Elément

Composant

Cela nous permet d’avoir complètement accès à tous les éléments du chemin d’accès. Si notre désir est d’une nature plus simple, nous pouvons nous servir d’une des méthodes qui nous permettent de manipuler le dernier composant, ce qui est généralement suffisant. Ces méthodes sont :

-lastPathComponent,

-stringByAppendingPathComponent:

, et

-stringByDeletingLastPathComponent

.

Elles travaillent comme leur nom le suggère. Si le chemin d’accès mentionné ci-dessus leur était communiqué,

NSString *thisColumn = @”/Users/mike/Documents/Cocoa_Column/Column8.doc”

alors nous pourrions faire les choses suivantes avec :

NSString *lastComponent = [thisColumn lastPathComponent]; NSString *pathLessFilename = [thisColumn stringByDeletingLastPathComponent]; NSString *originalPath = [pathLessFilename stringByAppendingPathComponent:lastComponent];

Au final, originalPath est équivalent à thisColumn. Ce qui s’est passé tient dans le fait que nous avons généré une nouvelle chaîne dans la première ligne, à partir du dernier composant de thisColumn retourné par lastPathComponent (nickel ces noms de méthodes, n’est ce pas ?), c’est à dire : “Column8.doc“. Dans la ligne suivante, nous avons créé une autre chaîne à partir du répertoire d’emplacement de “Column8.doc“, puis dans la dernière ligne nous avons combiné les deux pour reconstruire le chemin d’accès originel.

Bon, vous avez vu une petite poignée des méthodes disponibles pour manipuler les chemins d’accès. Vous pouvez les voir toutes dans la documentation de référence de la classe NSString; naturellement, cette documentation va beaucoup plus en profondeur.

Passons maintenant à ces chaînes qui peuvent être transformées !

Chaînes transformables

Précédemment dans notre discussion sur NSString, j’ai mentionné le fait que les chaînes en Cocoa sont fondamentalement des tableaux immuables de caractères Unicode. Cela veut dire qu’à partir du moment où une chaîne est créée, nous sommes bloqués sur elle et il n’y a rien que nous puissions en faire en utilisant la classe NSString. NSMutableString est notre solution. NSMutableString est une sous-classe de la classe NSString qui nous permet de faire exactement ce que nous pouvions pas faire auparavant - nous pouvons maintenant créer des chaînes qui possèdent la faculté de modifier, d’éditer ou de transformer leurs contenus.

Compte tenu que NSMutableString est une sous-classe de NSString, tout ce que nous avons appris sur les chaînes dans les articles précédents et dans celui-là reste valable pour les chaînes transformables. Dans cette section, je veux vous promener dans toutes les méthodes que NSMutableString ajoute à NSString et qui nous permettent d’éditer le contenu de chaînes transformables (je parlerai d’instances de NSString sous forme de “chaînes” et d’instances de NSMutableString sous forme de “chaînes transformables”).

Nous avons deux méthodes pour ajouter une chaîne à la fin d’une chaîne transformable existante : - appendString: et - appendFormat:, et elles fonctionnent comme suit :

NSMutableString *aMutableString = [[NSMutableString alloc] initWithString:@”Hello”]; [aMutableString appendString:@", World!"];

Le message appendString envoyé à aMutableString lui demande d’ajouter l’argument du message en fin de chaîne, ainsi le résultat obtenu est “Hello, World!”. Deux choses sont à noter ici. D’abord, nous ne pouvons utiliser le mode @”…” pour créer directement des chaînes transformables. Souvenez-vous que ce mode crée des chaînes qui sont compilées et toujours présentes en mémoire. Evidemment, nous ne pouvons modifier une chaîne pré-compilée et devons donc créer un nouvel objet NSMutableString comme tout objet, en utilisant les méthodes alloc et init. Toutefois, nous pouvons utiliser n’importe quelle méthode init… déclarée dans la classe NSString, car cette classe est la classe parente de la classe NSMutableString.

Additionnellement, notez qu’une des méthodes d’édition de contenu de la classe NSMutableString retourne une valeur dont le type est “void” (vide). Comme à l’accoutumée, ces méthodes ont plus pour objet de modifier la valeur de la chaîne réceptrice (du message) que d’en retourner une copie modifiée.

Nous pouvons aussi ajouter une chaîne formatée en fin d’une chaîne existante en utilisant -appendFormat:. Cette méthode fonctionne exactement de la même manière que la précédente, excepté que vous pouvez formater la chaîne en vous basant sur les principes appris dans l’article précédent.

La méthode - deleteCharactersInRange: accepte une portée (de type NSRange) comme argument et retire, de la chaîne réceptrice, les caractères compris dans cet intervalle. Pour former une portée, le programme-cadre “Foundation” fournit la fonction (une vraie fonction C, à ne pas confondre avec une méthode) NSMakeRange (départ int non-signé, longueur int non-signé), qui prend deux arguments qui sont les composants de la portée, et retourne une variable de type NSRange. Le premier argument représente la position de la première lettre (pensez tableau - le comptage part de 0) et le second argument la longueur de la portée, premier caractère inclus. Nous pourrions retirer la chaîne ajoutée dans l’exemple précédent de manière à retrouver le “Hello” originel :

NSRange aRange = NSMakeRange(5, 8); [aMutableString deleteCharactersInRange:aRange];

Une autre méthode de la classe NSMutableString, est - insertString: atIndex: dont le but est d’insérer la chaîne passée en premier argument dans une position indexée passée en deuxième argument. Ainsi, les caractères de la chaîne réceptrice qui se trouvent à partir de la position spécifiée se déplacent tous vers la fin de la chaîne de manière à constituer un espace d’accueil suffisamment grand pour la chaîne à insérer. Nous pourrions utiliser cette méthode comme suit :

NSMutableString *aMutableString = [[NSMutableString alloc] initWithString:@”Hello, World!”; [aMutableString insertString:@" (not goodbye)" atIndex:5];

qui transformerait aMutableString en “Hello (not goodbye), World!”. Notez que le premier caractère du mot que nous avons inséré est un espace. Rappelez vous que les tableaux sont indexés en partant de 0, ainsi le “H” de aMutableString est en position 0.

Si nous voulons changer complètement la valeur d’une chaîne, nous pouvons nous servir de la méthode -setString:. Ainsi, nous pouvons prendre la chaîne qui résulte de l’opération ci-dessus et la changer en ce que nous voulons avec cette méthode :

[aMutableString setString:@"whatever."];

ce qui a pour conséquence de changer la valeur de aMutableString en “whatever.”. Cette méthode doit vous rappeler les méthodes set… de la classe NSControl que nous avons apprises.

La dernière méthode intéressante de notre boite à outils pour chaînes transformables est - replaceCharactersInRange: withString:, qui fait exactement ce que son nom indique qu’elle fera. Le premier argument est une portée indiquant les caractères à retirer de la chaîne réceptrice et, le deuxième est la chaîne que vous voulez mettre à la place - en fait une simple opération de remplacement. Voyons comment elle fonctionne :

NSMutableString *aString = [[NSMutableString alloc] initWithString:@”Hello, World!”;]; [aString replaceCharactersInRange:NSMakeRange(7,5) withString:@"Universe"];

Et notre chaîne originelle devient alors “Hello, Universe!”.

Diverses petites choses sur les chaines

Avant la fin de cet article, je veux passer en revue diverses fonctionnalités de la classe NSString qui permettent de modifier la casse d’une chaîne ou d’obtenir la valeur numérique d’une chaîne.

Dans l’article relatif au colorimètre, nous avons parlé de la possibilité d’obtenir des valeurs numériques à partir d’un composant d’interface en envoyant à l’objet un des messages suivants : intValue, doubleValue, et floatValue. Ceci est aussi valable pour les chaînes. En fait, la classe NSString répond à ces messages de la manière que nous avons apprise pour les composants d’interface (pensez polymorphisme). La seule restriction tient dans le fait que l’objet string ne peut être qu’un nombre pour que ces méthodes fonctionnent. Nous ne pouvons utiliser ces méthodes pour obtenir un nombre à partir d’une chaîne. Nous pouvons par contre trouver un nombre dans une chaîne puis en retourner sa valeur de type C. Supposons que nous ayons une chaîne constituée de texte et d’un nombre en dernière position.

Nous pourrions sortir ce nombre de la chaîne comme suit :

NSString *textAndNumbers = @”Number of eggs in a dozen= 12″; NSString *numberPart = [textAndNumbers substringFromIndex:27]; int numberInADozen = [numberPart intValue];

Je l’admets, cet exemple est un peu arrangeante, mais j’imagine que vous vous faites une idée de cette possibilité. Rappelez vous, nous devons utiliser la correcte méthode …Value en fonction du type de nombre contenu dans la chaîne et du type de donnée de destination.

Un dernier échantillon de la folie de la classe NSString que je veux partagé avec vous est constitué des méthodes qui permettent de modifier la casse du texte d’une chaîne : -capitalizedString, -lowercaseString, et - uppercaseString. -lowercaseString retourne une chaîne dont tous les caractères de la chaîne réceptrice sont en minuscules, -uppercaseString fait la même chose mais avec des majuscules, -capitalizedString retourne une chaîne où la première lettre de chaque mot de la chaîne réceptrice est transformée en capitale. Voici ces méthodes en action :

NSString *string = @”tHe uniVERSity of TEXAS”; NSString *lcstring = [string lowercaseString]; NSString *ucstring = [string uppercaseString]; NSString *capstring = [string capitalizedString];

Ces trois dernières lignes convertissent la chaîne en “the university of texas”, “THE UNIVERSITY OF TEXAS”, et “The University Of Texas”, dans cet ordre.

Pensées finales

Dans cet article nous avons juste effleuré la surface du pouvoir de Cocoa dans la gestion des chaînes. J’ai indiqué d’un bout à l’autre de cet article que vous devriez jeter un oeil à la documentation de référence de la classe NSString (j’espère que les pages de référence des classes Foundation et Application Kit sont maintenant ajoutées à vos favoris !) de manière à obtenir des informations plus détaillées sur les autres méthodes que nous n’avons pas abordées ici. J’ai voulu vous apprendre les bases de la manipulation de chaînes de caractères en vous apportant l’assurance et la connaissance nécessaires à une étude plus profonde de la classe NSString. Dans le prochain article, nous nous mettrons à la tache d’apprendre comment développer de bonnes habitudes pour gérer correctement la mémoire.

http://www.macdevcenter.com/

http://www.macdevcenter.com/

Textes originaux en anglais sur O’Reilly : http://www.macdevcenter.com/pub/au/159

Thierry Programmation Cocoa , , ,

  1. Pas encore de commentaire
  1. Pas encore de trackbacks
S'abonner aux commentaires de cet article