Accueil Accueil     Membres Membres     Forum Forum     Articles Articles     Download Download     Sondages Sondages     Outils Outils     Scriptland Scriptland     ProgBoards ProgBoards     FR  
  Morbleu ! Morbleu ! Thomas Hobbes, Léviathan
Cours de programmation, code source, aide au développement, forums d'entraide - CybWarrior

login Bug Contact RSS
login bug contact RSS


| Internet |
   Créer son site web

| Langages |
   HTML
   JavaScript
   Langage C
   PHP
   QBasic
   Turbo Pascal

| Programmation |
   Algorithmie
   Maths appliquées
   Windows

| Trucs & astuces |
   Lexique
   Oeufs de Pâques (easter eggs)
   Registre et Windows

| Téléchargements |
   Flash
   Freeware
   JavaScript
   NASM
   PHP
   QBasic
   Turbo Pascal
   Visual Basic / VBScript

QBasic - L'accès aux fichiers

Autre langage disponible pour cet article : FR
Rubrique : QBasic
lundi 25 mars 2002 18:44

Voir les commentaires pour QBasic - L'accès aux fichiers
Autres articles :
- QBasic - Introduction au QBasic
- QBasic - Ecrire sur l'écran
- QBasic - Mathématiques élémentaires
- QBasic - La ponctuation (syntaxe)
- QBasic - Les variables
- QBasic - Les commentaires
- QBasic - Les constantes
- QBasic - Entrée de données
- QBasic - Les boucles inconditionnelles
- QBasic - Les boucles conditionnelles
- QBasic - Structure conditionnelle
- QBasic - Les cas
- QBasic - Maths, logique et divers
- QBasic - Le texte
- QBasic - Le son
- QBasic - Dessiner
- QBasic - Sous-programmes, fonctions et procedures
- QBasic - Les types de variables
- QBasic - Les tableaux
- QBasic - Les types personalisés
- QBasic - L'organisation des données
- QBasic - QBasic et le système d'exploitation
- QBasic - L'accès aux fichiers
- QBasic - Le traitement des erreurs
- QBasic - La manette de jeu
- QBasic - Encore plus loin dans le graphisme
- QBasic - La mémoire
- QBasic - Le langage machine et la souris
- QBasic - L'heure, la date, le temps
- QBasic - Le clavier
<< - >>

  1. Les fichiers à accès séquentiel
  2. Les fichiers à accès aléatoire
  3. Les fichiers binaires
  4. Fonctions et instructions complémentaires
    1. FREEFILE
    2. LOF
    3. LOC
    4. SEEK
Outre gérer les fichiers via le DOS, QBasic a aussi la capacité de lire les fichiers et d'écrire dedans. Il existe trois types de fichiers. Les fichiers à accès séquentiel, les fichiers à accès aléatoire et les fichiers binaires.

Les fichiers à accès séquentiel

Nous allons tout d'abord voir comment écrire dans un fichier. Pour écrire dans un fichier, il faut déjà que celui ci existe. Si il existe, il n'y a qu'à l'ouvrir. Sinon, il faut le créer. L'instruction OPEN est une instruction clef de l'accès aux fichiers. En effet, elle sert aussi bien pour créer des fichiers, ou pour les ouvrir.
Pour créer un fichier, on utilise OPEN ainsi :
OPEN "C:\Warrior.txt" FOR OUTPUT AS #1
Détaillons. OPEN ouvre le fichier C:\Warrior.txt. FOR est utilisé pour préciser le mode d'accès. Ici, le mode est OUTPUT (sortie in English), pour écrire. Ensuite, il faut assigner à ce fichier un numéro par le biais du mot-clef AS. Ici, comme c'est le premier fichier que l'on ouvre, on lui donne le numéro 1.
Maintenant, nous allons écrire dedans. Pour écriren, on utilise soit PRINT, soit WRITE. La différence entre les deux, c'est que WRITE écrit avec des guillemets et des virgules entre les termes.
On utilise PRINT comme pour écrire à l'écran. On rajoute seulement le numéro du fichier dans lequel écrire :
OPEN "C:\Warrior.txt" FOR OUTPUT AS #1           ' ouverture du fichier en écriture
  PRINT #1, "Ceci est un texte dans un fichier"  ' écriture dans le fichier #1
CLOSE #1                                         ' fermeture
Dans cet exemple, le programme écrit la chaîne Ceci est un texte dans un fichier dans le fichier #1 (C:\Warrior.txt).
L'instruction CLOSE ferme le fichier dont le numéro le suit. Il faut TOUJOURS fermer un fichier, au mieux après son utilisation, au pis à la fin du programme, sinon les effets peuvent être désastreux.
Maintenant, pour lire dans ce fichier, on utilise toujours OPEN, mais cette fois le mode d'accès sera différent : on utilisera le mode INPUT.
' Création du fichier C:\Warrior.txt avec du texte à l'intérieur
OPEN "C:\Warrior.txt" FOR OUTPUT AS #1
  PRINT #1, "Ceci est un texte dans un fichier"
CLOSE #1

' Lecture du fichier créé précédement
OPEN "C:\Warrior.txt" FOR INPUT AS #1
  INPUT #1, Texte$
CLOSE #1
PRINT "Le texte du fichier est : "; Texte$
Que c'est-il passé ? On a tout simplement lu l'intérieur du fichier à l'aide de l'instruction INPUT. La variable Texte$ qui suit INPUT prend alors la valeur de ce qui doit être lu. Ensuite, on a fermé le fichier (TOUJOURS!), puis afficher le contenu de la variable Texte$.
Maintenant, si on avait eu un nombre indéterminé de lignes dans le fichier, comment aurrait-on fait ? Analysez ce petit programme de bloc-notes (sommaire). Il y a aussi une ou deux procédures.
COMMON SHARED Fichier$

Fichier$ = "C:\Notes.txt"
CLS

DO
  PRINT "[L]ire | [E]crire | [Q]uitter"
  DO
    Touche$ = UCASE$(INKEY$)
  LOOP UNTIL Touche$ <> ""
  
  SELECT CASE Touche$
  CASE "L"
    Lire
  CASE "E"
    Ecrire
  END SELECT
LOOP UNTIL Touche$ = "Q"
END

SUB Ecrire()
' Cette procédure ecrit dans le fichier
CLS
PRINT "Ecrire sautez une ligne pour finir"
PRINT

OPEN Fichier$ FOR OUTPUT AS #1
  DO
    LINE INPUT Texte$
    PRINT #1, Texte$
  LOOP UNTIL Texte$ = ""
CLOSE #1
END SUB

SUB Lire()
' Cette procédure lit le contenu du fichier et l'affiche
CLS
PRINT "*** Bloc-Notes ***"
PRINT

OPEN Fichier$ FOR INPUT AS #1
  DO UNTIL EOF(1) = -1
    LINE INPUT #1, Ligne$
    PRINT Ligne$
  LOOP
CLOSE #1
END SUB
Certaines instructions n'ont encore pas été vues jusqu'ici :
  • INKEY$ : cette instruction renvoie l'état d'une touche du clavier lors de son appelle. C'est à dire que si la touche 'T' est enfoncée, INKEY$ vaudra 'T'. Mais si la touche était 't', INKEY$ vaudrais 't'. C'est pourquoi on converti le retour de INKEY$ en lettres majuscules à l'aide de l'instruction UCASE$.
  • EOF : EOF renvoi -1 (TRUE) si la fin du fichier dont le numéro lui est associé est atteinte. Le numéro est le celui entre parenthéses (ici, 1).
  • LINE INPUT : on a tout simplement rajouté LINE devant INPUT. Cette associtation a pour effet de lire une ligne de 255 caractères, que ce soit sur l'écran ou dans un fichier.
On peut dire que ce petit programme est structuré, puisque l'on a respecté une certaine méthode.
  • Dans la boucle DO...LOOP, on commence par afficher le menu rudimentaire.
  • Ensuite l'execution du programme est suspendue jusqu'à ce que l'utilisateur appuie sur une touche.
  • Puis, à l'aide d'une structure SELECT...CASE, on analyse la commande et on la traite. Si la commande est 'L' (Lire le fichier), on execute la procédure 'Lire'. Si la commande est 'E' (Ecrire dans le fichier), on execute la procédure 'Ecrire'. En revanche, si la commande est 'Q' (Quitter), on sort de la boucle, ce qui a pour effet de terminer le programme avec l'instruction END.
Détaillons maintenant les deux procédures :
  • Ecrire : cette procédure écrit dans le fichier définit au départ dans la variable Fichier$. Pour cela, on ouvre le fichier avec OPEN et l'accés OUTPUT, pour pouvoir écrire dedans. On lui attribut le numéro 1.
    Puis on rentre dans une boucle DO...LOOP. Cette boucle demande à l'utilisateur d'entrer du texte. Ce texte est ensuite écrit dans le fichier. Si l'utilisateur entre une ligne vierge, la boucle se termine. Le fichier est alors refermé avec l'instruction CLOSE.
  • Lire : cette procédure lit le fichier et affiche le contenu sur l'écran. Le fichier est comme d'habitude ouvert avec l'instruction OPEN. Cependant, le mode d'accès différe puisqu'on utilise INPUT.
    Et comme dans la procédure détaillée précédemment, on entre dans une boucle DO...LOOP. On lit alors toute une ligne du fichier avec LINE INPUT puis on l'écrit sur l'écran avec PRINT. La boucle se termine lorsque la fin du fichier est atteinte, c'est à dire lorque EOF vaut -1 (TRUE). Puis on referme le fichier.
Mais vous aurrait certainement remarqué qu'à chaque fois que l'on veut écrire dans le fichier, l'ancien contenu est effacé. Si on avait voulu écrire à la suite et conservé les anciennes données, il aurrait falut utiliser un autre mode d'accès que OUTPUT : APPEND.
APPEND ouvre le fichier en écriture, tout comme OUTPUT, mais à ce détail près que toutes les informations sont écrite à la fin du fichier. Modifiez donc le mode d'accès de la procédure Ecrire de notre précédent exemple par APPEND.
COMMON SHARED Fichier$

Fichier$ = "C:\Notes.txt"
CLS

DO
  PRINT "[L]ire | [E]crire | [Q]uitter"
  DO
    Touche$ = UCASE$(INKEY$)
  LOOP UNTIL Touche$ <> ""
  
  SELECT CASE Touche$
  CASE "L"
    Lire
  CASE "E"
    Ecrire
  END SELECT
LOOP UNTIL Touche$ = "Q"
END

SUB Ecrire()
' Cette procédure ecrit dans le fichier
CLS
PRINT "Ecrire sautez une ligne pour finir"
PRINT

OPEN Fichier$ FOR APPEND AS #1               ' changement du mode d'accès
  DO
    LINE INPUT Texte$
    PRINT #1, Texte$
  LOOP UNTIL Texte$ = ""
CLOSE #1
END SUB

SUB Lire()
' Cette procédure lit le contenu du fichier et l'affiche
CLS
PRINT "*** Bloc-Notes ***"
PRINT

OPEN Fichier$ FOR INPUT AS #1
  DO UNTIL EOF(1) = -1
    LINE INPUT #1, Ligne$
    PRINT Ligne$
  LOOP
CLOSE #1
END SUB
Comme prévu, les lignes sont belles et biens rajoutées à la fin du fichier.
Ce qu'on ne vous a pas dit :
  • Lors de l'ouverture d'un fichier avec les modes d'accés INPUT et APPEND, le fichier doit OBLIGATOIREMENT exister. Dans le cas contraire, une erreur 'Fichier non trouvé' se produit.
  • Comme pour du texte à l'écran, on peut utiliser l'instruction PRINT USING pour écrire du texte en forme, avec le numéro du fichier après PRINT, naturellement.

Les fichiers à accès aléatoire

Vous avez vu que les fichiers à accès séquentiel ne permettent pas d'aller directement à un enregistrement bien déterminé. C'est pourquoi il existe une autre race de fichiers : les fichiers à accès aléatoire.
Ce dernier mode d'accès est très utile pour réaliser des bases de données. En fait, ces fichiers permettent d'enregistrer un type définit par l'utilitsateur. Ainsi, pour un fichier qui aurrait gérer les clients d'une société, on aurrait pu écrire un programme tel que celui-ci :
TYPE TClient
  Numero AS INTEGER
  Societe AS STRING * 30
  Nom AS STRING * 30
  Prenom AS STRING * 30
  Telephone AS STRING * 30
  Fax AS STRING * 30
  Email AS STRING * 30
END TYPE
COMMON SHARED Fichier$

Fichier$ = "C:\Clients.txt"

DO
  PRINT "[N]ouveau client | [A]ller à | [Q]uitter"
  DO
    Touche$ = UCASE$(INKEY$)
  LOOP UNTIL Touche$ <> ""
  SELECT CASE Touche$
  CASE "N"
    Nouveau
  CASE "A"
    Aller
  END SELECT
LOOP UNTIL Touche$ = "Q"
END

SUB Nouveau()
DIM Client AS TClient
CLS
PRINT "*** Création d'un nouveau client ***"
PRINT
INPUT "Numéro client : ", Client.Numero
INPUT "Société : ", Client.Societe
INPUT "Nom : ", Client.Nom
INPUT "Prénom : ", Client.Prenom
INPUT "Telephone : ", Client.Telephone
INPUT "Fax : ", Client.Fax
INPUT "Email : ", Client.Email

OPEN Fichier$ FOR RANDOM AS #1 LEN = LEN(Client)
  PUT #1, Client.Numero, Client
CLOSE #1
END SUB

SUB Aller()
DIM Client AS TClient
CLS
PRINT "*** Aller à un numéro de client ***"
PRINT
INPUT "Numéro du client à rechercher : ", Numero

OPEN Fichier$ FOR RANDOM AS #1 LEN = LEN(Client)
  GET #1, Numero, Client
CLOSE #1

PRINT "Société : ", Client.Societe
PRINT "Nom : ", Client.Nom
PRINT "Prénom : ", Client.Prenom
PRINT "Telephone : ", Client.Telephone
PRINT "Fax : ", Client.Fax
PRINT "Email : ", Client.Email
END SUB
L'utilisation de ce programme est très simple. Pour créer un client, on appuie sur la touche 'n'. À ce moment, il faut préciser le numéro du client. Attention ! Si un client était déjà affecté à se numéro, les données seront écrasées.
Si on veut retrouver une fiche client, on appuie sur la touche 'A'. L'ordinateur demande alors le numéro de la fiche à laquelle il doit aller.
Bien sur, on aurrait put créer des routines, des procédures et des fonctions permettant de rechercher, filtrer, classer, compter, anlyser les enregistrements, mais le but de ce chapitre est une simple démonstration des capacités des fichiers à accès aléatoire.

Mais regardons plutôt comment ça marche. Passons sur le corps principal du programme, vous êtes désormais familiarisé avec ce genre de menu. Remarquez seulement la définition du type. Comme c'est un type, tout les champs STRING doivent être délimités. Ici on a mis 30 caractères, mais on aurrait tout a fait pu en mettre 50 ou 5. Le principal, c'est qu'il soit définis.
Allons voir ce qu'il ce passe dans la procédure 'Nouveau'. Déjà, on déclare une variable 'Client' du type 'TClient' définit précédemment. Puis, à l'aide des instructions INPUT, on assigne des valeurs au différents champs.
Ensuite, il faut stocker ces données dans le fichier. On ouvre alors le fichier avec OPEN, et le mode d'accès RANDOM, pour un accès aléatoire. Comme nous somme en mode aléatoire, il faut spécifier la longueur de chaque enregistrement avec LEN en octets.
Attention ! Il ne faut pas confondre ces deux LEN ! Le premier posséde une valeur qui est définie par l'autre instruction LEN. Comme vous le savez, LEN donne la longueur d'une chaîne de caractères. Dans ce contexte, LEN donne le nombre d'octets occupé par la variable 'Client'. On aurrait tout aussi bien pu mettre une constante d'octets que l'on aurrait calculé à partir de notre type : Numéro (2 octets) + Societe (30 octets) + Nom (30 octets) + Prenom (30 octets) + Telephone (30 octets) + Fax (30 octets) + Email (30 octets) = 182 octets. Donc, la ligne aurrait pu s'écrire :
OPEN Fichier$ FOR RANDOM LEN = 182
Ensuite, comme pour un fichier séquentiel, il faut stocker les données. Mais ici, c'est avec PUT qu'il faut oppérer.
On spécifie le numéro du fichier, le numéro de l'enregistrement, puis la variable A ECRIRE.
Et comme un fichier traditionnel, on le referme.
Pour la procédure 'Aller', c'est presque pareil. On définit la variable, on demande le numéro de l'enregistrement à consulter, on ouvre le fichier avec RANDOM sans oublier de fixer la taille des enregistrements, puis là on utilise non pas PUT, non pas INPUT, ni LINE INPUT, mais GET pour accéder à l'enregistrement spécifié.
Avec GET, on spécifie le numéro du fichier, le numéro de l'enregistrement, puis la variable où l'on va STOCKER la lecture du fichier.
Ensuite, on a afficher la variable.

Les fichiers binaires

À proprement parler, les fichiers binaires ne sont pas un type disinct. En fait, ouvrire un fichier en mode d'accès binaire permet de modifier n'importe quel octet à n'importe quel emplacement. Le mode d'accès binaire va ouvrir le fichier sans prendre en compte les éventuelles liaisons qu'il pourrait y avoir si c'était un fichier à accès aléatoire.
Voici un exemple qui ouvre un fichier de votre choix et affiche son contenu à la manière d'un éditeur Hexadécimal.
SCREEN 0
WIDTH 80, 50
DIM Octet AS STRING * 1
INPUT "Nom du fichier à ouvrir : ", Fichier$
CLS
OPEN Fichier$ FOR BINARY AS #1
  FOR i = 1 TO LOF(1)
    GET #1, i, Octet
    PRINT HEX$(ASC(Octet)) + SPACE$(1); 
    IF i / 4 = INT(i / 4) THEN PRINT ,
    IF i / 16 = INT(i / 16) THEN 
      FOR j = i - 15 TO i
        GET #1, j, Octet
        IF Octet < SPACE$(1) THEN Octet = SPACE$(1)
        PRINT Octet;
      NEXT j
      PRINT : PRINT
    END IF
  NEXT i
CLOSE #1
Comme il est désormais coutume avec les fichiers, on ouvre le fichier avec OPEN. Ici, le mode d'accès s'appelle BINARY. Ensuite, on entre dans une boucle. L'instruction LOF retourne la longueur en octets du fichiers dont le numéro lui est passé. Ensuite, pour lire un octet, on utilise GET, suivit du numéro du fichier, de l'octet à lire, et de la variable dans laquelle stocker la lecture. Tout le reste, les IF...THEN, ASC, HEX$, INT, FOR...NEXT, PRINT n'est que mise en scène afin d'afficher de manière propre les données.
Maintenant, si on avait voulu écrire au lieu de lire, on aurrait tout simplement utilisé l' instruction PUT, suivit du numéro du fichier dans lequel écrire, de l'emplacement de l' octet où écrire et de la variable contenant la valeur de l'octet.

Fonctions et instructions complémentaires

FREEFILE

À chaque fois que l'on ouvre un fichier alors que d'autres sont déjà ouverts, il faut lui allouer un numéro. Or, il arrive que dans des programmes employant des boucles ou autres, on ne sache pas quel numéro employer. Heuresement, l'instruction FREEFILE est là et renvoi le prochain numéro de fichier disponible :
Num = FREEFILE                       ' FREEFILE renvoi le prochain numéro
     ' de fichier disponible
OPEN "C:\Notes.txt" FOR INPUT AS Num
CLOSE Num

LOF

Il est parfois utile de connaître la longueur d'un fichier, pour une raison ou pour une autre. LOF (Length Of File) renvoi la longueur (en octets) du fichier dont le numéro lui est passé en argument. Le fichier doit donc être ouvert pour pouvoir être pesé :
OPEN "C:\Notes.txt" FOR INPUT AS #1
  PRINT "La taille du fichier est de "; LOF(1); " octets."
CLOSE #1

LOC

Lorsqu'un fichier est ouvert, si on veut connaître la position actuelle du pointeur dans le fichier, on utilise l'instruction LOC. LOC n'a pas le même effet selon le type d'accès du fichier :
  • Accès séquentiel : retourne la position de l'octet pointé, mais divisé par 128.
  • Accès aléatoire : renvoi le numéro du dernier enregistrement lu ou écrit.
  • Accès binaire : retourne la position du dernier octet lu ou écrit.

SEEK

SEEK est un peu particulier, puisque c'est à la fois une fonction et une instruction (pour rappel, une fonction renvoi une valeur, alors qu'une instruction non).
La fonction retourne la postion actuelle du pointeur dans un fichier.
L'instrucion spécifie la position de ce même pointeur pour la prochaine opération d'écriture ou de lecture.

Voir les commentaires pour QBasic - L'accès aux fichiers
 06 juillet 2008 | Version 4.0.0 | © 2001 - 2007