Une remarque pertinente ?
Une critique impertinente ?
Un lynchage en règle ?
Une invitation sous les tropiques ?

Ecrivez-moi !
Conçu et enseigné tel qu'en lui même, avec pertes, fracas et humour de qualité supérieure            
 par Christophe Darmangeat dans le M2 PISE du Master MECI (Université Paris 7)            

 
 
 
  
 
 
 
Partie 14
Les fichiers texte
 
Comme nous l'avons vu lors d'un excellentissime cours d'algorithmique, malgré les progrès et la sophistication croissante des langages de programmation, le fichier texte reste la voie la plus rustique - mais aussi une des plus sûres - pour stocker des données entre deux exécutions d'un programme. Aussi allons-nous traiter de l'accès aux fichiers, en nous cantonnant à la technique de base : le fichier texte en accès séquentiel. C'est ce qu'on appelle un chapitre - relativement - reposant.
1. Les instructions liées aux fichiers texte
Bon, là, quand on connaît la musique - c'est-à-dire le concept du fichier texte - il n'y a plus qu'à apprendre la syntaxe. Le plus difficile, c'est d'arriver à choisir, parmi la pelletée d'instructions que propose VB pour traiter des fichiers texte (et ça ne manque pas, ils sont vraiment fous !) une bonne petite technique qui soit simple et qui marche bien. Bande de petits veinards, ce boulot, c'est moi qui me le suis cogné, et voilà le résultat de mes savantes recherches.
Pour ouvrir un fichier texte, le plus facile est de passer par l'instruction FileOpen, selon la syntaxe suivante :
FileOpen(numéro, nom du fichier, mode)
  • numéro est un entier compris entre 1 et 255 (ça devrait suffire assez largement...)
  • nom du fichier est une chaîne de caractères
  • mode est une valeur choisie parmi OpenMode.Input (ouverture en lecture), OpenMode.Output (ouverture en écriture) ou OpenMode.Append (ouverture en ajout)
Ensuite, pour recopier la ligne suivante du ficher numéro 3 dans la variable Toto, on écrira :
Toto = LineInput(3)
De même, pour recopier la variable Tutu en tant que ligne dans le fichier numéro 5, on écrira :
PrintLine(5, Toto)
La fonction retournant une valeur booléenne indiquant si l'on se trouve à la fin du fichier est évidemment EOF(), avec le numéro dudit fichier en paramètre. Enfin, pour fermer le fichier numéro 1, on emploiera :
FileClose(1)
Voilà. On ne peut pas dire que tout cela fasse bien mal à la tête.
2. Récupérer les lignes dans des variables
C'est là qu'on commence à rire pour de bon.
En effet, jusque là, dans tout langage civilisé, une des stratégies qui fonctionnait en toutes circonstances, pour le traitement des fichiers texte comme pour celui des fichiers binaires, consistait à travailler avec des structures. Ces structures étaient définies de manière à "coller" avec la manière dont les données étaient rangées dans les fichiers.
En ce qui concerne les fichiers texte, cela revenait à organiser les données - dans le fichier - sous la forme de champs de largeur fixe. Et à employer, en mémoire vive, une structure elle aussi "de largeur fixe", composée de chaînes de caractères au nombre de caractères déterminés une bonne fois pour toutes. Tout n'était peut-être pas pour le mieux dans le meilleur des mondes possibles, mais disons qu'on s'en approchait tranquillement. Eh bien, la nouvelle neuve du jour, c'est qu'avec VB.Net, il n'existe plus de chaînes de largeur fixe. Adieu donc les structures telles que nous les avons connues, et adieu les fichiers texte organisés sous forme de champs de largeur fixe. C'est beau, le progrès, non ?
Alors, à défaut de pouvoir faire ce qu'on veut, on n'a plus qu'à se résoudre à faire ce qu'on peut. C'est-à-dire à se rabattre sur les fichiers texte organisés sous forme de champs délimités.
Petit rappel :
Cela signifie que sur chaque ligne (enregistrement) de notre fichier, les différentes informations (les différents champs) seront séparés par un caractère séparateur (on le choisit généralement parmi la tabulation, la virgule, le point-virgule, et quelques autres).
Il va donc falloir, à chaque lecture de ligne du fichier, procéder à un découpage de cette ligne entre les différentes variables qui la composent. Mais comme nous avons de la chance dans notre malheur, nous allons pouvoir nous dispenser de nous taper une boucle lisant cette ligne caractère par caractère, afin d'y localiser les occurrences du caractère séparateur (chose qui était inéluctable dans les langages traditionnels). VB .Net propose en effet deux fonctions de découpage et de recomposition automatique des chaînes, qui vont grandement soulager notre peine. Voyons donc :
La fonction Split permet de constituer automatiquement un tableau de Strings à partir d'une chaîne de caractères dans laquelle figure un caractère de séparation. Ainsi, en exécutant le code suivant :
Dim S As String
Dim R() As String
S ="Ceci/est/un/message/codé"
R = Split(S, "/")
On récupère un tableau R de cinq cases, la première contenant "Ceci", la seconde "est", la troisième "un", etc. Et VB.Net autorisant des écritures beaucoup plus synthétiques, nous pouvons réécrire le code ci-dessus en deux coups de cuiller à pot :
Dim S As String = "Ceci/est/un/message/codé"
Dim R() As String = Split(S, "/")
Éventuellement, rien ne nous empêche ensuite de rebasculer les différents éléments de R dans une structure, ou dans un tableau de structures, si nous trouvons cela plus pratique (et il y a neuf chances sur dix pour que cela le soit effectivement). Simplement, je réinsiste, il ne s'agira pas de structures comportant des chaînes de longueur fixe.
Dans l'autre sens, nous trouvons en quelque sorte l'exact inverse de la fonction Split, en la personne de la fonction Join, puisque celle-ci constitue une chaîne unique à partir d'un tableau de Strings et d'un séparateur. Ainsi, si je repars du tableau R constitué un peu plus haut et que j'écris :
Dim Z As String
Z = Join(R, ";")
Z contiendra "Ceci;est;un;message;codé". Magique, non ? Évidemment, on aurait même pu se contenter de :
Dim Z As String = Join(R, ";")
Résumons-nous :
  • Split permet de récupérer dans un tableau les différents champs à partir d'une ligne d'un fichier texte organisée par un caractère séparateur
  • Join permet, à l'inverse, de constituer une ligne organisée par un caractère séparateur à partir de différents champs rangés dans un tableau.
On peut donc dégager le processus-type pour le traitement d'un fichier texte sous VB.Net (sachant que ce fichier devra être organisé via un caractère séparateur) :
  1. déclaration d'une structure adéquate
  2. déclaration d'un tableau de cette structure, non dimensionné
  3. boucle de lecture du fichier, au sein de laquelle, pour chaque ligne :
  4. on lit la ligne suivante
  5. on la découpe par Split dans un tableau de Strings (de stockage temporaire)
  6. on agrandit le tableau des structures
  7. on recopie les informations du tableau de stockage temporaire vers le nouvel emplacement du tableau de structures
  8. fin de la boucle
Et voilà. Ensuite, on procède à tous les traitements nécessaires (en mémoire vive, comme il se doit). Lorsque c'est terminé, on recopie le tableau de structures vers le fichier :
  1. boucle de parcours du tableau de structure
  2. pour chaque élément, on recopie les informations dans un tableau de Strings temporaire
  3. on constitue par Join une chaîne à partir du tableau temporaire
  4. on copie cette chaîne dans le fichier
  5. fin de la boucle
Vous auriez préféré que j'écrive le code ? Ben voyons... Il faut tout de même que je vous laisse quelques occasions de vous dérouiller les neurones.
L'exercice qui suit, sans être vraiment méchant, n'est pas particulièrement facile. Il demande de gérer un fichier texte - vous le trouverez ci-dessous.
Il pose également (et surtout ?) quelques problèmes liés à la gestion d'une seconde Form, problèmes que nous avions évité jusque là, et dont je ne traite pas dans ce site, mais qu'il faut bien aborder un jour ou l'autre. C'est ici un cas assez facile, sur lequel vous trouverez des indications sur le site de Microsoft.
Quant au score obtenu lors de ce grand jeu, il s'agit tout bêtement d'un nombre aléatoire entre 1 et 1000.
Exercice
Exécutable
Fichier
Sources
Top 100