Chapitre 6 — Types de Données chaînes
Une chaîne est une suite de caractères de texte. Nous signalons au
BASIC que nous travaillons
avec du texte plutôt qu'avec des noms de variables en mettant le texte entre guillemets.
En appliquant ceci, on doit voir clairement pourquoi, si l'on veut afficher
« Bonjour » sur l'écran, nous écrivons :
PRINT "Bonjour"
et pas
PRINT Bonjour
Le deuxième exemple enverrait le
BASIC se précipiter vers
sa liste de variables pour essayer d'en trouver une nommée Bonjour. Si, par extraordinaire,
vous en aviez une, il afficherait sa valeur, mais il y a peu de chances que ce soit le cas, donc le
BASIC va manifester
son mécontentement.
On peut comparer la façon dont une variable de type chaîne stocke sa valeur à une série de cases
en mémoire dont chacune contient un caractère, comme ceci :
Les guillemets ne sont pas conservés comme faisant partie du texte ;
ils ne sont utilisés
que comme des délimiteurs pendant la programmation. Chaque position a une taille de un octet,
ce qui signifie qu'elle peut contenir un nombre compris entre 0 et 255. Aussi, si un octet
ne peut contenir qu'un nombre, comment stocke-t-il les lettres comme ci-dessus ?
La réponse, c'est que le système opérationnel possède un tableau de comparaison qu'il utilise
pour traduire votre texte en codes numériques pour les stocker en mémoire et ensuite les retraduire
quand on veut les afficher. Le tableau est appelé tableau
ASCII
(les programmeurs adorent les sigles – et cela signifie Code américain standard pour l'échange
d'informations). Ce tableau fournit la correspondance avec les lettres, les chiffres, les signes
de ponctuation et divers autres caractères. Lorsque nous stockons les lettres de
« Bonjour », elles sont en fait représentées dans l'ordinateur comme ceci :
Il vous est possible de voir le tableau complet dans
l'Aide en ligne (Help Topics ou F1), Appendice B (Reference Information),
§ 1 (Table of ASCII codes). Remarquez que tous les codes n'ont pas une représentation visible
et que les codes inférieurs à 32 risquent de provoquer des choses étranges si vous essayez de
les afficher. Ces codes entre 1 et 31 sont souvent appelés caractères de contrôle parce qu'ils
représentent des choses comme la tabulation horizontale, le changement de page, etc. De la même façon,
les nombres supérieurs à 127 correspondent à un standard qui n'est pas standard (!) et
eux aussi donneront des caractères différents selon la police de caractères qui est installée.
Regardez le caractère 32, l'espace. Normalement, notre cerveau élimine automatiquement
l'espace lorsque nous lisons un texte : l'espace est là, mais nous l'ignorons. Pour un ordinateur,
l'espace a pourtant besoin d'une représentation, aussi une valeur lui est donnée, exactement comme
tous les autres signes de ponctuation comme la virgule (code 44) ou le point qui sert
aussi de point décimal (code 46). Comme le
BASIC est si tatillon
au sujet des espaces, cela signifie que les deux chaînes :
"Bonjour"
et :
" Bonjour"
seraient considérées comme différentes ; comme nous l'avons dit,
notre œil élimine l'espace, mais pour l'ordinateur ce n'est qu'un autre code de caractère.
De la même façon que les nombres ont des limites, les chaînes en ont aussi. Les limites sont
le code du caractère (de 0 à 255) et le nombre de caractères que la variable chaîne
peut contenir, c'est-à-dire la longueur de la chaîne. Dans
« BB4W »
la longueur peut aller de 0 à 65535 caractères. Zéro, parce qu'il peut y avoir une chaîne
qui ne contienne rien. En fait, lorsqu'une variable chaîne est déclarée pour la première fois, le
BASIC la crée avec
une longueur de zéro, c'est-à-dire avec rien à l'intérieur. Cela peut paraître quelque peu étrange,
mais c'est un concept utile. Si, à tout moment, vous souhaitez déclarer une chaîne qui ne contient rien,
voici ce que vous ferez :
MaChaine$ = ""
C'est-à-dire des guillemets ouvrant et fermant avec aucun espace à l'intérieur. Comme l'espace
est un caractère, ce n'est pas la même chose que :
MaChaine$ = " "
Si vous deviez les afficher, vous ne verriez pas de différence mais, bien sûr, cela ne signifie pas
qu'elles sont identiques. Une chaîne qui ne contient rien est appelée soit une chaîne vide
soit une chaîne nulle. Vous rencontrerez les deux.
Maintenant que nous maîtrisons les chaînes, que pouvons-nous en faire ?
Avec les variables numériques, on peut additionner, soustraire, extraire la racine carrée etc.
Les chaînes sont un peu plus limitées. On ne peut que les ajouter :
REM Ajout de chaînes
S1$ = "Bonjour"
S2$ = ", "
S3$ = "tout le monde"
S4$ = S1$ + S2$
PRINT S4$
S4$ = S4$ + S3$
PRINT S4$
END
On appelle ceci la concaténation, mot bizarre qui signifie les enchaîner l'une à l'autre.
Le programme copie le contenu de S1$, colle S2$ à la suite et met le résultat dans S4$. La
ligne 7 ajoute S3$ à la fin de S4$. Rien ne vous empêcherait de faire tout cela sur une seule ligne.
REM Concaténation
S1$ = "Bonjour"
S2$ = ", "
S3$ = "tout le monde"
S4$ = S1$ + S2$ + S3$
PRINT S4$
END
Voilà la seule opération mathématique autorisée sur les chaînes. Aucune autre opération n'a de sens,
de toute façon : comment extraire la racine carrée de "Bonjour" ? Pourtant, ne croyez pas
un seul instant que c'est tout ce qu'il faut savoir : le
BASIC a une série de fonctions
très complète pour manipuler les variables chaînes. C'est dans la section suivante qu'on en parlera.
Fonctions chaînes
LEN
L'une des choses les plus utiles qu'on puisse connaître pour une chaîne, c'est sa longueur.
La fonction
LEN
nous le dit exactement. Elle doit toujours avoir un argument, bien que, comme cela est habituel,
ce puisse être une expression. Le résultat doit toujours être affecté à une variable numérique
ou être utilisé dans une expression où l'on attend une valeur numérique. En mode direct,
essayez ce qui suit :
PRINT LEN("Bonjour")
PRINT LEN("Bonjour, tout le monde")
On peut utiliser
LEN
pour faire la différence entre une chaîne vide et une chaîne qui n'a pas de caractères visibles :
REM LEN : Longueur d'une chaîne vide
A$=""
B$=" "
PRINT LEN(A$)
PRINT LEN(B$)
END
STRING$
Il arrive que vous vouliez pouvoir générer la répétition d'un texte sans avoir à le taper manuellement.
STRING$
fait exactement cela. Il prend comme paramètres le nombre de répétitions et une chaîne de base.
Il renvoie une chaîne qui est la chaîne de base répétée le nombre de fois voulu par le nombre donné :
PRINT STRING$(3,"+++===")
Voici un petit programme qui prend une chaîne, puis la souligne.
REM Souligner avec LEN et STRING$
Titre$ = "BBC BASIC"
L%=LEN(Titre$)
PRINT Titre$
PRINT STRING$(L%,"*")
END
Ou bien, juste pour nous entraîner, nous pourrions mettre le titre dans un cadre :
REM Cadre avec LEN et STRING$
Titre$ = "BBC BASIC"
L%=LEN(Titre$)
PRINT STRING$(L%+4,"*")
PRINT "* ";Titre$;" *"
PRINT STRING$(L%+4,"*")
END
INSTR
Bien qu'il soit facile de créer des chaînes, il arrive qu'on veuille examiner leur contenu. La fonction
INSTR nous permet de chercher dans une chaîne un caractère ou un groupe de caractères.
INSTR prend deux ou trois arguments. Le premier est la chaîne que nous voulons examiner.
Le second est une chaîne qui contient les caractères que nous voulons chercher. Le troisième est
facultatif–; nous y reviendrons dans un instant. Lorsqu'elle a deux arguments, la fonction
INSTR renvoie la position du premier caractère de la chaîne de recherche
qui correspond aux caractères de la liste à rechercher. Cet exemple renverra la position de la
première lettre C dans la chaîne cible :
PRINT INSTR("BBC BASIC", "C")
Le premier caractère d'une chaîne est à la position 1. Si
INSTR renvoie 0, cela signifie qu'aucune correspondance n'a été trouvée.
PRINT INSTR("BB4W", "C")
Le troisième paramètre optionnel peut forcer
INSTR à commencer à une autre position que la position 1. Cela signifie que
nous pouvons chercher dans la chaîne entière en nous souvenant de la dernière position renvoyée
et en commençant au caractère qui suit.
REM INSTR Démonstration
Posn%=INSTR("BBC BASIC","C")
PRINT "C trouvé à la position : ";Posn%
Posn%=Posn%+1
osn%=INSTR("BBC BASIC","C",Posn%)
PRINT "C trouvé à la position : ";Posn%
END
Remarquez que nous devons incrémenter Posn% (= lui ajouter 1)
pour le faire aller au-delà du premier C. Si nous ne l'avions pas fait, nous aurions recommencé
à la position 3. Comme à la position 3 il y a un C, la recherche aurait de nouveau renvoyé la même valeur.
Si la position de départ est supérieure à la longueur de la chaîne, vous obtenez 0 (= pas trouvé)
comme réponse.
INSTR
peut aussi chercher une suite de caractères dans la chaîne cible.
PRINT INSTR("BBC BASIC","BBC")
Il faut être ici très prudent dans la manière de spécifier la chaîne à rechercher.
PRINT INSTR("BBC BASIC FOR WINDOWS","FOR")
PRINT INSTR("L'UNION FAIT LA FORCE","FOR")
Les deux recherches vous diront que les deux chaînes contiennent toutes deux le mot "FOR",
alors qu'il est clair que la deuxième ne le contient pas. Cela est dû au fait que le
BASIC ne connaît rien
à la langue, ne fait que rechercher une suite de caractères, et quand il trouve une correspondance,
il s'arrête. Il serait plus correct de rechercher :
PRINT INSTR("BBC BASIC FOR WINDOWS","FOR ")
PRINT INSTR("L'UNION FAIT LA FORCE","FOR ")
LEFT$ et RIGHT$
Les deux fonctions suivantes renvoient une sous-section de la chaîne. Nous les traitons
ensemble parce qu'elles fonctionnent de la même manière.
LEFT$
prend deux paramètres : une chaîne cible et un nombre de caractères. On a en réponse une chaîne
qui a la longueur donnée par le nombre de caractères, en commençant à la position 1.
PRINT LEFT$("Bonjour, tout le monde", 7)
Si le nombre est plus grand que la longueur totale de la chaîne, vous n'obtenez rien d'autre
que la chaîne tout entière.
PRINT LEFT$("Bonjour, tout le monde", 100)
LEFT$
peut aussi n'accepter qu'un seul paramètre :
PRINT LEFT$("Bonjour")
On aura comme réponse tous les caractères de la chaîne sauf le dernier. C'est la même chose que :
PRINT LEFT$("Bonjour", LEN("Bonjour")-1)
Il est aussi possible d'utiliser
LEFT$
comme affectation. Dans ce mode,
LEFT$
remplacera les caractères de la chaîne cible par ceux de la chaîne d'affectation, en commençant
au premier caractère.
REM LEFT$ comme affectation
MaChaine$="Bonjour, tout le monde"
LEFT$(MaChaine$,8)="A demain"
PRINT MaChaine$
END
Si vous spécifiez un nombre plus petit que la longueur du remplacement, le
BASIC ne remplacera
que le nombre de caractères spécifiés. Si vous en donnez davantage, le
BASIC ne fera
le remplacement que pour le nombre maximum de caractères dans la chaîne de remplacement.
RIGHT$
prend les mêmes arguments que
LEFT$
mais renvoie le nombre de caractères indiqués à droite.
PRINT RIGHT$("Bonjour, tout le monde", 5)
Là aussi, si le nombre de caractères est trop élevé, vous n'avez en retour que la chaîne entière.
Avec un seul argument,
RIGHT$
ne renvoie que le dernier caractère.
Comme on pouvait s'y attendre, lorsqu'il est utilisé dans une affectation,
RIGHT$
remplace les caractères de la fin de la chaîne.
REM RIGHT$ comme affectation
MaCh$="Bonjour, tout le monde"
RIGHT$(MaCh$,10)="s les amis"
PRINT MaCh$
END
Ce qui se passe exactement si l'on spécifie moins de caractères que la longueur de la chaîne
de remplacement sera probablement mieux illustré par un exemple. Changez le 10 en 9 à la
ligne 3 ci-dessus et voyez ce qui se passe. L'opération commence à 9 caractères de la fin et
les 9 premiers caractères de la chaîne de remplacement sont copiés. Si on dit au
BASIC d'utiliser
plus de caractères qu'il n'en existe dans la chaîne, notre gentil ordinateur en tirera effectivement
son propre nombre. À la ligne 3, utilisez maintenant 13 et voyez. Le remplacement ne commence pas
à 13 caractères de la fin de la chaîne : l'ordinateur voit que la chaîne de remplacement
a 10 caractères, et il commence alors à cette position.
Veuillez noter qu'avec
LEFT$
aussi bien qu'avec
RIGHT$,
il n'est pas possible d'augmenter la longueur de la chaîne d'origine en donnant plus de caractères
dans la chaîne de remplacement qu'il n'y en a dans la chaîne cible. Le
BASIC se contentera
de tronquer la chaîne de substitution à la longueur de la chaîne cible.
MID$
LEFT$
et
RIGHT$
permettent la manipulation du début et de la fin d'une chaîne, mais comment extraire des caractères du
milieu ?
MID$
va faire cela pour nous.
Dans son application la plus courante,
MID$
a trois paramètres : une chaîne, la position de départ et un nombre de caractères. Comme dans toutes
les chaînes, le caractère le plus à gauche est à la position 1. Essayez ceci :
PRINT MID$("L'union fait la force", 9, 4)
Ceci renvoie 4 caractères, en commençant à la position 9, c'est-à-dire « fait »
dans cet exemple.
Si le dernier nombre est plus grand que le nombre de caractères dans la chaîne, on obtient
simplement tous les caractères jusqu'à la fin.
PRINT MID$("L'union fait la force", 9, 1000)
Ce cas est si courant que le
BASIC nous permet d'omettre
le paramètre final. Si vous faites ceci,
BASIC interprète
que vous voulez tous les caractères de la position de départ jusqu'à la fin.
PRINT MID$("L'union fait la force", 9)
Bon ; ça, c'était relativement facile, mais nous n'en avons pas encore fini. Comme
RIGHT$
et
LEFT$,
MID$
peut aussi être utilisé de l'autre côté du signe égale. Cela signifie que vous pouvez demander au
BASIC de remplacer
une portion de chaîne :
REM MID$ démonstration
A$ = "Donnez-moi de la patience !"
MID$(A$,18,8) = "maîtrise"
PRINT A$
END
À partir de cette description, vous devriez être capable de deviner ce qui se passe.
On explique : la ligne 3 prend la chaîne « maîtrise » qui est longue de
8 caractères et, en commençant à la position 18 de A$, remplace les caractères un à un avec
les caractères de « maîtrise ».
Il faut être conscient de plusieurs choses quand on traite du nombre de caractères. D'habitude,
le nombre est le même que la longueur de la chaîne de remplacement. Si le nombre de caractères spécifiés
est plus petit que la longueur de remplacement, c'est seulement ce nombre de caractères qui sera copié :
MID$(A$,18,4) = "maîtrise"
Également, si la somme de la position de départ dans la chaîne cible et du nombre
de caractères est plus grande que la longueur totale de la chaîne de remplacement, le
BASIC ne copiera
les caractères que jusqu'à la fin de la chaîne cible et ignorera tout ce qui suit :
MID$(A$,18,13) = "monnaie sonnante"
On peut dire cela autrement : le
BASIC n'augmentera pas
la longueur de la chaîne cible.
On peut ne pas exprimer le nombre de caractères. Dans ce cas, le
BASIC en déduit la longueur
de la chaîne de remplacement, mais en obéissant toujours aux règles énoncées ci-dessus.
Voyons maintenant une petite démonstration qui utilise
INSTR,
LEFT$
et
MID$.
Supposons que nous avons le nom complet d'une personne et que nous voulions le séparer en prénom
et nom. Nous savons que les deux noms sont séparés par l'espace, aussi allons-nous tout d'abord
utiliser
INSTR
pour localiser l'espace. Et puis nous copions tous les caractères jusqu'à l'espace, mais sans l'inclure,
dans la chaîne qui stocke le prénom. Ensuite, nous prenons toutes les lettres qui commencent après l'espace,
jusqu'à la fin, et nous les enregistrons dans le nom. Essayez-vous y vous-même tout de suite avant de
regarder mon résultat, si vous voulez : c'est la seule façon d'apprendre.
REM Séparation du prénom et du nom
NomComplet$ = "Jean Bonneaux"
Posn% = INSTR(NomComplet$, " ")
Prenom$ = LEFT$(NomComplet$, Posn%-1)
Nom$ = MID$(NomComplet$, Posn%+1)
PRINT "Votre prénom est : ";Prenom$
PRINT "Votre nom est : ";Nom$
END
Comment avez-vous fait ? Il y a toujours autant de façons de coder la solution d'un programme
qu'il y a de personnes qui essaient de le coder, aussi si vous avez obtenu une solution différente,
c'est bien. Ne soyez pas non plus vexé si vous n'avez pas réussi complètement à faire juste du premier
coup–; moi non plus : tout cela fait partie du processus de la programmation.
ASC et CHR$
Nous avons déjà fait la connaissance du tableau
ASCII.
Il est très utile pour pouvoir trouver les codes qui correspondent aux lettres et vice versa. C'est là
qu'interviennent
ASC et
CHR$.
ASC
renvoie un entier qui est le code
ASCII
du caractère passé en paramètre :
PRINT ASC("A")
donne 65, comme on s'y attendait.
Notez aussi que :
PRINT ASC("1")
donne 49, qui est le code pour le caractère "1", et n'est pas
la valeur 1.
Si la chaîne comporte plus d'un caractère,
ASC renvoie
le code du premier caractère. Pour inspecter les autres positions, on a besoin d'utiliser
MID$ :
PRINT ASC(MID$("BB4W",2,1))
qui donne le code du second caractère, "B".
Comme vous pouvez vous y attendre,
CHR$
fait le contraire de
ASC :
donnez-lui un nombre et il renverra une chaîne d'un seul caractère contenant le code
ASCII correspondant.
PRINT CHR$(65)
CHR$
est particulièrement utile pour fabriquer des chaînes avec des caractères impossibles à obtenir
sur un clavier standard :
PRINT "1000 litres valent 1 m"+CHR$(179)
Ceci peut être une technique utile pour imprimer des caractères de contrôle du curseur
ou des caractères définis par l'utilisateur, et que l'on décrira dans une section ultérieure.
Si vous donnez à
CHR$
un nombre supérieur à 256, le
BASIC le divise par 256
et donne le caractère correspondant au reste.
Un truc : Pour imprimer des guillemets
|
Si vous voulez imprimer des guillemets dans une chaîne, vous pouvez le faire de deux façons.
La première implique de construire une chaîne qui contient
CHR$(34),
c'est-à-dire le code du guillemet.
Salut$ = CHR$(34) + "Bonjour, toi" + CHR$(34)
PRINT Salut$
L'autre façon est un petit truc que nous permet
« BB4W ».
On peut en fait mettre le guillemet dans la chaîne, mais il faut en mettre deux l'un après l'autre
pour que le
BASIC sache
que nous voulons imprimer le caractère guillemet et donc, que ce n'est pas la fin de la chaîne.
Salut$ = """Bonjour, toi"""
PRINT Salut$
Comme les guillemets de cette chaîne sont au début et à la fin, il y en a trois, ce qui paraît
vraiment bizarre. Partons du début : le premier indique le début de la chaîne et les deux
autres disent au
BASIC de stocker
un guillemet. À la fin c'est pareil, dans l'autre sens.
|
VAL et STR$
Les deux commandes suivantes nous permettent de faire des conversions entre les types de données
numériques et chaînes.
VAL
prend comme argument la représentation d'un nombre sous forme de chaîne et renvoie l'équivalent
numérique de ce nombre.
PRINT VAL("123")
Si la chaîne contient une information non numérique, elle convertira jusqu'à ce qu'elle ne le puisse
plus :
PRINT VAL("123xyz")
ou bien, si l'information non numérique est placée en premier, on obtient simplement 0.
PRINT VAL("xyz123")
La contrepartie de
VAL
est
STR$,
ce que vous aviez probablement deviné. Vous avez peut-être deviné aussi que
STR$
prend un nombre ou une variable numérique et fait la conversion pour donner une chaîne.
On peut maintenant ajouter un nombre à une chaîne :
REM STR$ démonstration
A$ = "Température extérieure = " + STR$(21.6)
PRINT A$
END
Il y a des réglages par défaut qui contrôlent le format de la chaîne produite. Tout est bien
documenté dans
l'Aide en ligne,
et cela peut être changé pour l'exécution si vous le voulez, mais ça dépasse un peu l'objectif de ce Guide
pratique.
EVAL
La dernière commande de chaîne qui doive être mentionnée est
EVAL. Je vais
vous donner une idée de ce qu'elle peut faire plutôt que de donner une description complète,
parce que c'est une commande tellement puissante. En gros, elle permet d'évaluer le contenu
d'une expression chaîne. Prenez la description de
VAL,
qui convertit une chaîne en nombre. Il arrive que, par moments, les programmeurs essaient,
par inadvertance ou non, quelque chose comme :
PRINT VAL("22/7")
VAL
renvoie 22, comme cela a été décrit plus haut. Essayez maintenant :
PRINT EVAL("22/7")
N'êtes-vous pas impressionné ? Essayez :
PRINT EVAL("SIN(PI/2)")
Croyez-moi sur parole : ça, ce n'est pas quelque chose que vous pouvez faire avec n'importe quel
BASIC ancien.
Vous pouvez passer n'importe quelle expression chaîne et
EVAL
l'évaluera et renverra une valeur chaîne ou numérique, exactement comme si vous aviez entré le code
dans une ligne de programme. Comme on l'a démontré plus haut, vous pouvez utiliser les fonctions internes de
BBC BASIC
(bien que des commandes comme
CLS, etc. ne fonctionneront pas).
Vous pouvez même utiliser des variables à l'intérieur du programme :
REM EVAL démonstration
Cote1 = 3
Cote2 = 4
Hyp = EVAL("SQR(Cote1^2+Cote2^2)")
PRINT "L'hypoténuse vaut : ";Hyp
END
Les possibilités offertes par ceci se diluent dans l'infini, aussi est-ce tout ce que je vais
en dire ici.
Exercices
06.1
Créez une chaîne pour contenir les jours de la semaine, comme ceci :
"Lun Mar MercJeu VendSam Dim "
Tous les noms ont 4 caractères, y compris l'espace si nécessaire. En partant d'un nombre pour un jour,
utilisez
MID$
pour extraire l'abréviation correcte correspondant à ce jour.
06.2
Faites une chaîne pour contenir votre prénom. Utilisez
MID$
et ASC pour
trouver les codes
ASCII des lettres du prénom.
06.3
Définissez trois chaînes pour contenir votre prénom, votre second prénom (si vous n'en avez pas,
inventez-vous en un) et votre nom de famille. Utilisez
LEFT$
pour trouver vos initiales et utilisez la concaténation pour créer une nouvelle chaîne similaire
à « R. T. Russell ».
Fin du Chapitre 6
|