Skip to content

6. Les fichiers texte

Un fichier texte est un fichier contenant des lignes de texte. Examinons la création et l'utilisation de tels fichiers sur des exemples.

6.1. Création et utilisation

Programme

Résultats

C:\>cscript fic1.vbs

C:\>dir

FIC1     VBS           352  07/01/02   7:07 fic1.vbs
TESTFILE TXT            25  07/01/02   7:07 testfile.txt

C:\>more testfile.txt

Ceci est un autre test.

Commentaires

  • la ligne 7 crée un objet fichier de type "Scripting.FileSystemObject" par la fonction CreateObject("Scripting.FileSystemObject"). Un tel objet permet l'accès à tout fichier du système pas simplement à des fichiers texte.
  • la ligne 9 crée un objet "TextStream". La création de cet objet est associée à la création du fichier testfile.txt. Ce fichier n'est pas désigné par un nom absolu du genre c:\dir1\dir2\....\testfile.txt mais par un nom relatif testfile.txt. Il sera alors créé dans le répertoire d'où sera lancée la commande d'exécution du fichier.
  • le système de fichiers du système windows n'a pas connaissance de concepts tels que fichier texte ou fichier non texte. Il ne connaît que des fichiers. C'est donc au programme qui exploite ce fichier de savoir s'il va le traiter comme un fichier texte ou non.
  • La ligne 9 crée un objet d'où la commande set utilisée pour l'affectation. La création d'un objet fichier texte passe par la création de 2 objets :
    • la création d'un objet Scripting.FileSystemObject (ligne 7)
    • puis par la création d'un objet "TextStream" (fichier texte) par la méthode OpenTextFile de l'objet Scripting.FileSystemObject qui admet plusieurs paramètres :
      • le nom du fichier à gérer (obligatoire)
      • le mode d'utilisation du fichier. C'est un entier avec 3 valeurs possibles :
        • 1 : utilisation du fichier en lecture
        • 2 : utilisation du fichier en écriture. S'il n'existe pas déjà et si le 3ième paramètre est présent et a la valeur true, il est créé sinon il n'est pas. S'il existe déjà, il est écrasé.
        • 8 : utilisation du fichier en ajout, c.a.d. écriture en fin de fichier. Si le fichier n'existe pas déjà et si le 3ième paramètre est présent et a la valeur true, il est créé sinon il n'est pas.
  • la ligne 11 écrit une ligne de texte avec la méthode WriteLine de l'objet TextStream créé.
  • la ligne 13 "ferme" le fichier. On ne peut alors plus écrire ou lire dedans.
  • la ligne 16 crée un nouvel objet "TextStream" pour exploiter le même fichier que précédemment mais cette fois-ci en mode "ajout". Les lignes qui seront écrites le seront derrière les lignes existantes.
  • la ligne 18 écrit deux nouvelles lignes sachant que la constante vbCRLF est la marque de fin de ligne des fichiers texte.
  • la ligne 20 ferme de nouveau le fichier
  • la ligne 23 le rouvre en mode "lecture" : on va lire le contenu du fichier.
  • La ligne 27 lit une ligne de texte avec la méthode ReadLine de l'objet TextStream. Lorsque le fichier vient d'être "ouvert", on est positionné sur la 1ère ligne de texte de celui-ci. Lorsque celle-ci a été lue par la méthode ReadLine, on est positionné sur la seconde ligne. Ainsi la méthode Readline non seulement lit la ligne courante mais "avance" ensuite automatiquement à la ligne suivante.
  • Pour ligne toutes les lignes de texte, la méthode ReadLine doit être appliquée de façon répétée dans une boucle. Celle-ci (ligne 26) se termine lorsque l'attribut AtEndOfStream de l'objet TextStream a la valeur true. Cela signifie alors qu'il n'y a plus de lignes à lire dans le fichier.

6.2. Les cas d'erreur

On rencontre deux cas d'erreur fréquents :

  • ouverture en lecture d'un fichier qui n'existe pas
  • ouverture en écriture ou ajout d'un fichier qui n'existe pas avec comme le troisième paramètre à false dans l'appel à la méthode OpenTextFile.

Le programme suivant montre comment détecter ces erreurs :

Programme

' création & remplissage d'un fichier texte
Option Explicit
Dim objFichier,MyFile
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim codeErreur

' on crée un objet fichier
Set objFichier=CreateObject("Scripting.FileSystemObject")

' on ouvre un fichier texte devant exister en lecture
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForReading)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then  
    ' le fichier n'existe pas
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
    ' on ferme le fichier texte  
    MyFile.Close
End If


' on ouvre un fichier texte devant exister en écriture
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForWriting, False)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then  
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
    ' on ferme le fichier texte
    MyFile.Close
End If

' on ouvre un fichier texte devant exister en ajout
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForAppending, False)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then  
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
    ' on ferme le fichier texte
    MyFile.Close
End If

' fin
wscript.quit 0

Résultats

C:\>dir

FIC1     VBS           964  07/01/02   7:54 fic1.vbs
TESTFILE TXT             0  07/01/02   8:18 testfile.txt
FIC2     VBS         1 252  07/01/02   8:23 fic2.vbs
3 fichier(s)              2 216 octets
2 répertoire(s)        4 007.11 Mo libre

C:\>cscript fic2.vbs

Le fichier [abcd] n'existe pas
Le fichier [abcd] n'existe pas
Le fichier [abcd] n'existe pas

6.3. L'application IMPOTS avec un fichier texte

Nous reprenons l'application de calcul de l'impôt en supposant que les données nécessaires au calcul de l'impôt sont dans un fichier texte appelé data.txt :

12620 13190 15640 24740 31810 39970 48360 55790 92970 127860 151250 172040 195000 0
0 0,05 0,1 0,15 0,2 0,25 0,3 0,35 0,4 0,45 0,5 0,55 0,6 0,65
0 631 1290,5 2072,5 3309,5 4900 6898,5 9316,5 12106 16754,5 23147,5 30710 39312 49062

Les trois lignes contiennent respectivement les données des tableaux limites, coeffR et coeffN de l'application. Grâce à la modularisation de notre application, les modifications interviennent essentiellement dans la procédure getData chargée de construire les trois tableaux. Le nouveau programme est le suivant :

Programme

' calcul de l'impôt d'un contribuable
' le programme doit être appelé avec trois paramètres : marié enfants salaire
' marié : caractère O si marié, N si non marié
' enfants : nombre d'enfants
' salaire : salaire annuel sans les centimes

' déclaration obligatoire des variables
Option Explicit
Dim erreur

' on récupère les arguments en vérifiant leur validité
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' erreur ?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)

' on récupère les données nécessaires au calcul de l'impôt
Dim limites, coeffR, coeffN
erreur=getData(limites,coeffR,coeffN)
' erreur ?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit 5

' on affiche le résultat
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)

' on quitte sans erreur
wscript.quit 0

' ------------ fonctions et procédures

' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
    ' doit récupérer trois valeurs passées comme argument au programme principal
    ' un argument est transmis au programme sans espaces devant et derrière
    ' on utilisera des expression régulières pour vérifier la validité des données

    ' rend un variant tableau erreur à 2 valeurs
    ' erreur(0) : code d'erreur, 0 si pas d'erreur
    ' erreur(1) : message d'erreur si erreur sinon la chaîne vide

    Dim syntaxe
    syntaxe= _
    "Syntaxe : pg marié enfants salaire" & vbCRLF & _
    "marié : caractère O si marié, N si non marié" & vbCRLF & _
    "enfants : nombre d'enfants (entier >=0)" & vbCRLF & _
    "salaire : salaire annuel sans les centimes (entier >=0)"

    ' on vérifie qu'il y a 3 arguments
    Dim nbArguments
    nbArguments=wscript.arguments.count
    If nbArguments<>3 Then
        ' msg d'erreur
        getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
        ' fin
        Exit Function
    End If

    Dim modele, correspondances
    Set modele=new regexp

    ' le statut marital doit être parmi les caractères oOnN
    modele.pattern="^[oOnN]$"
    Set correspondances=modele.execute(wscript.arguments(0))
    If correspondances.count=0 Then
        ' msg d'erreur
        getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
        ' on quitte
        Exit Function
    End If
    ' on récupère la valeur
    If lcase(wscript.arguments(0)) = "o"Then
        marie=true
    Else
        marie=false
    End If

    ' enfants doit être un nombre entier >=0
    modele.pattern="^\d{1,2}$"
    Set correspondances=modele.execute(wscript.arguments(1))
    If correspondances.count=0 Then
        ' erreur
        getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
        ' on quitte
        Exit Function
    End If
    ' on récupère la valeur
    enfants=cint(wscript.arguments(1))

    ' salaire doit être un entier >=0
    modele.pattern="^\d{1,9}$"
    Set correspondances=modele.execute(wscript.arguments(2))
    If correspondances.count=0 Then
        ' erreur
        getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
        ' on quitte
        Exit Function
    End If
    ' on récupère la valeur
    salaire=clng(wscript.arguments(2))

    ' c'est fini sans erreur
    getArguments=array(0,"")
End Function

' ----------- getData
Function getData(byref limites, ByRef coeffR, ByRef coeffN)
    ' les données des trois tableaux limites, coeffR, coeffN sont dans un fichier texte
    ' appelé data.txt. Chaque tableau occupe une ligne sous la forme val1 val2 ... valn
    ' on trouve dans l'ordre limites, coeffR, coeffN

    ' rend un variant erreur tableau à 2 éléments pour gérer l'éventuelle erreur
    ' erreur(0) : 0 si pas d'erreur, un nombre entier >0 sinon
    ' erreur(1) : le message d'erreur si erreur

    Dim objFichier,MyFile,codeErreur
    Const ForReading = 1, dataFileName="data.txt"

    ' on crée un objet fichier
    Set objFichier=CreateObject("Scripting.FileSystemObject")
    ' on ouvre le fichier data.txt en lecture
    On Error Resume Next
    Set MyFile= objFichier.OpenTextFile(dataFileName, ForReading)
    ' erreur ?
    codeErreur=err.number
    On Error GoTo 0
    If codeErreur<>0 Then
        ' il y a eu erreur - on la note
        getData=array(1,"Impossible d'ouvrir le fichier des données [" & dataFileName & "] en lecture")
        ' on rentre
        Exit Function
    End If

    ' on suppose maintenant que le contenu est correct et on ne fait aucune vérification
    ' on lit les 3 lignes

    ' limites
    Dim ligne, i
    ligne=MyFile.ReadLine
    getDataFromLine ligne,limites

    ' coeffR
    ligne=MyFile.ReadLine
    getDataFromLine ligne,coeffR


    ' coeffN
    ligne=MyFile.ReadLine
    coeffN=split(ligne," ")
    getDataFromLine ligne,coeffN

    ' on ferme le fichier
    MyFile.close

    ' c'est fini sans erreur
    getData=array(0,"")
End Function

' ----------- getDataFromLine
Sub getDataFromLine(byref ligne, ByRef tableau)
    ' met dans tableau les valeurs numériques contenues dans ligne
    ' celles-ci sont séparées par un ou plusieurs espaces

    ' au départ le tableau est vide
    tableau=array()
    ' on définit un modèle pour la ligne
    Dim modele, correspondances
    Set modele= New RegExP
    With modele
        .pattern="\d+,\d+|\d+"    ' 140,5 ou 140
        .global=true              ' toutes les valeurs
    End With

    ' on analyse la ligne
    Set correspondances=modele.execute(ligne)
    Dim i
    For i=0 To correspondances.count-1
        ' on redimensionne le tableau
        ReDim Preserve tableau(i)
        ' on affecte une valeur au nouvel élément
        tableau(i)=cdbl(correspondances(i).value)
    Next

    'fin
End Sub




' ----------- calculerImpot
Function calculerImpot(byval marie,ByVal enfants,ByVal salaire, ByRef limites, ByRef coeffR, ByRef coeffN)

    ' on calcule le nombre de parts
    Dim nbParts
    If marie=true Then
        nbParts=(enfants/2)+2
    Else
        nbParts=(enfants/2)+1
    End If
    If enfants>=3 Then nbParts=nbParts+0.5

    ' on calcule le quotient familial et le revenu imposable
    Dim revenu, qf
    revenu=0.72*salaire
    qf=revenu/nbParts

    ' on calcule l'impôt
    Dim i, impot
    i=0
    Do While i<ubound(limites) And qf>limites(i)
        i=i+1
    Loop
    calculerImpot=int(revenu*coeffr(i)-nbParts*coeffn(i))
End Function

Commentaires :

  • dans le fichier texte data.txt, les valeurs peuvent être séparées par un ou plusieurs espaces, d'où l'impossibilité d'utiliser la fonction split pour récupérer les valeurs de la ligne. Il a fallu passer par une expression régulière
  • la fonction getData rend, outre les trois tableaux limites, coeffR, coeffN, un résultat indiquant s'il y a eu erreur ou non. Ce résultat est un variant tableau de eux éléments. Le premier élément est un code d'erreur (0 si pas d'erreur), le second le message d'erreur s'il y a eu erreur.
  • la fonction getData ne teste pas la validité des valeurs trouvées dans le fichier data.txt. En situation réelle, elle devrait le faire.