Skip to content

6. Arquivos de texto

Um arquivo de texto é um arquivo que contém linhas de texto. Vamos examinar a criação e o uso desses arquivos por meio de exemplos.

6.1. Criação e utilização

Programa
Resultados
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.

Comentários

  • A linha 7 cria um objeto de arquivo do tipo “Scripting.FileSystemObject” por meio da função CreateObject("Scripting.FileSystemObject"). Esse objeto permite o acesso a qualquer arquivo do sistema, não apenas a arquivos de texto.
  • A linha 9 cria um objeto “TextStream”. A criação desse objeto está associada à criação do arquivo testfile.txt. Esse arquivo não é designado por um nome absoluto do tipo c:\dir1\dir2\....\testfile.txt, mas por um nome relativo, testfile.txt. Ele será, portanto, criado no diretório de onde será executado o comando para abrir o arquivo.
  • O sistema de arquivos do Windows não reconhece conceitos como arquivo de texto ou arquivo não textual. Ele reconhece apenas arquivos. Portanto, cabe ao programa que utiliza esse arquivo determinar se ele será tratado como um arquivo de texto ou não.
  • A linha 9 cria um objeto a partir do qual o comando set é utilizado para a atribuição. A criação de um objeto de arquivo de texto envolve a criação de dois objetos:
    • a criação de um objeto Scripting.FileSystemObject (linha 7)
    • e, em seguida, a criação de um objeto “TextStream” (arquivo de texto) pelo método OpenTextFile do objeto Scripting.FileSystemObject, que aceita vários parâmetros:
      • o nome do arquivo a ser processado (obrigatório)
      • o modo de utilização do arquivo. Trata-se de um número inteiro com três valores possíveis:
        • 1: uso do arquivo em modo de leitura
        • 2: uso do arquivo em gravação. Se ele ainda não existir e se o terceiro parâmetro estiver presente e tiver o valor true, ele será criado; caso contrário, não será. Se já existir, será sobrescrito.
        • 8: uso do arquivo em modo de adição, c.a.d. Gravação no final do arquivo. Se o arquivo ainda não existir e se o terceiro parâmetro estiver presente e tiver o valor “true”, ele será criado; caso contrário, não será.
  • A linha 11 grava uma linha de texto com o método WriteLine do objeto TextStream criado.
  • A linha 13 “fecha” o arquivo. A partir daí, não é mais possível gravar ou ler nele.
  • A linha 16 cria um novo objeto “TextStream” para operar o mesmo arquivo de antes, mas desta vez no modo “adição”. As linhas que forem escritas serão inseridas após as linhas existentes.
  • A linha 18 grava duas novas linhas, sabendo que a constante vbCRLF é o marcador de fim de linha dos arquivos de texto.
  • A linha 20 fecha o arquivo novamente
  • a linha 23 o reabre no modo “leitura”: vamos ler o conteúdo do arquivo.
  • A linha 27 lê uma linha de texto com o método ReadLine do objeto TextStream. Quando o arquivo acaba de ser “aberto”, o cursor está posicionado na primeira linha de texto do arquivo. Quando essa linha é lida pelo método ReadLine, o cursor passa para a segunda linha. Assim, o método Readline não apenas lê a linha atual, mas também “avança” automaticamente para a linha seguinte.
  • Para processar todas as linhas de texto, o método ReadLine deve ser aplicado repetidamente em um loop. Esse loop (linha 26) termina quando o atributo AtEndOfStream do objeto TextStream assume o valor true. Isso significa, portanto, que não há mais linhas para serem lidas no arquivo.

6.2. Casos de erro

Existem dois casos frequentes de erro:

  • abertura para leitura de um arquivo que não existe
  • abertura para gravação ou adição de um arquivo que não existe, com o terceiro parâmetro definido como false na chamada ao método OpenTextFile.

O programa a seguir mostra como detectar esses erros:

Programa
' criação e preenchimento de um arquivo de texto
Option Explicit
Dim objFichier,MyFile
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim codeErreur

' cria-se um objeto de arquivo
Set objFichier=CreateObject("Scripting.FileSystemObject")

' abre-se um arquivo de texto que já deve existir, em modo de leitura
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForReading)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then  
    ' o arquivo não existe
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
    ' fecha-se o arquivo de texto  
    MyFile.Close
End If


' abre-se um arquivo de texto que já deve existir para gravação
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
    ' fecha-se o arquivo de texto
    MyFile.Close
End If

' abrindo um arquivo de texto que deve existir em modo de adição
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
    ' fecha-se o arquivo de texto
    MyFile.Close
End If

' fim
wscript.quit 0
Resultados
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. O aplicativo IMPOTS com um arquivo de texto

Retomamos o aplicativo de cálculo de impostos, supondo que os dados necessários para o cálculo estejam em um arquivo de texto chamado 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

As três linhas contêm, respectivamente, os dados das tabelas de limites coeffR e coeffN do aplicativo. Graças à modularização do nosso aplicativo, as alterações ocorrem essencialmente no procedimento getData, responsável pela construção das três tabelas. O novo programa é o seguinte:

Programa
' cálculo do imposto de um contribuinte
' o programa deve ser chamado com três parâmetros: casado, filhos, salário
' casado: caractere O se casado, N se solteiro
' filhos: número de filhos
' salário: salário anual sem os centavos

' declaração obrigatória das variáveis
Option Explicit
Dim erreur

' os argumentos são recuperados verificando-se sua validade
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' erro?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)

' recuperam-se os dados necessários para o cálculo do imposto
Dim limites, coeffR, coeffN
erreur=getData(limites,coeffR,coeffN)
' erro?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit 5

' exibe-se o resultado
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)

' saída sem erros
wscript.quit 0

' ------------ funções e procedimentos

' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
    ' deve recuperar três valores passados como argumentos para o programa principal
    ' um argumento é transmitido ao programa sem espaços antes e depois
    ' serão utilizadas expressões regulares para verificar a validade dos dados

    ' retorna uma variante de tabela de erros com 2 valores
    ' erro(0): código de erro, 0 se não houver erro
    ' erro(1): mensagem de erro se houver erro; caso contrário, a string vazia

    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)"

    ' verifica-se se há 3 argumentos
    Dim nbArguments
    nbArguments=wscript.arguments.count
    If nbArguments<>3 Then
        ' mensagem de erro
        getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
        ' fim
        Exit Function
    End If

    Dim modele, correspondances
    Set modele=new regexp

    ' o estado civil deve estar entre os caracteres oOnN
    modele.pattern="^[oOnN]$"
    Set correspondances=modele.execute(wscript.arguments(0))
    If correspondances.count=0 Then
        ' mensagem de erro
        getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
        ' saindo
        Exit Function
    End If
    ' recuperando o valor
    If lcase(wscript.arguments(0)) = "o"Then
        marie=true
    Else
        marie=false
    End If

    ' filhos deve ser um número inteiro >=0
    modele.pattern="^\d{1,2}$"
    Set correspondances=modele.execute(wscript.arguments(1))
    If correspondances.count=0 Then
        ' erro
        getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
        ' saindo
        Exit Function
    End If
    ' recuperando o valor
    enfants=cint(wscript.arguments(1))

    ' o salário deve ser um número inteiro >= 0
    modele.pattern="^\d{1,9}$"
    Set correspondances=modele.execute(wscript.arguments(2))
    If correspondances.count=0 Then
        ' erro
        getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
        ' saindo
        Exit Function
    End If
    ' recuperamos o valor
    salaire=clng(wscript.arguments(2))

    ' concluído sem erros
    getArguments=array(0,"")
End Function

' ----------- getData
Function getData(byref limites, ByRef coeffR, ByRef coeffN)
    ' os dados das três tabelas de limites, coeffR, coeffN, estão em um arquivo de texto
    ' chamado data.txt. Cada tabela ocupa uma linha no formato val1 val2 ... valn
    ' encontram-se, nessa ordem, os limites coeffR e coeffN

    ' retorna uma variante de erro com tabela de 2 elementos para lidar com um possível erro
    ' erro(0): 0 se não houver erro; um número inteiro > 0 caso contrário
    ' erro(1): a mensagem de erro, caso haja erro

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

    ' cria-se um objeto de arquivo
    Set objFichier=CreateObject("Scripting.FileSystemObject")
    ' abre-se o arquivo data.txt para leitura
    On Error Resume Next
    Set MyFile= objFichier.OpenTextFile(dataFileName, ForReading)
    ' erro?
    codeErreur=err.number
    On Error GoTo 0
    If codeErreur<>0 Then
        ' ocorreu um erro — registramos o erro
        getData=array(1,"Impossible d'ouvrir le fichier des données [" & dataFileName & "] en lecture")
        ' insere-se
        Exit Function
    End If

    ' agora supõe-se que o conteúdo está correto e não se faz nenhuma verificação
    ' lemos as 3 linhas

    ' 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

    ' fecha-se o arquivo
    MyFile.close

    ' concluído sem erros
    getData=array(0,"")
End Function

' ----------- getDataFromLine
Sub getDataFromLine(byref ligne, ByRef tableau)
    ' insere em uma tabela os valores numéricos contidos na linha
    ' esses valores são separados por um ou mais espaços

    ' inicialmente, a tabela está vazia
    tableau=array()
    ' define-se um modelo para a linha
    Dim modele, correspondances
    Set modele= New RegExP
    With modele
        .pattern="\d+,\d+|\d+"    ' 140,5 ou 140
        .global=true              ' toutes les valeurs
    End With

    ' analisa-se a linha
    Set correspondances=modele.execute(ligne)
    Dim i
    For i=0 To correspondances.count-1
        ' redimensiona-se a tabela
        ReDim Preserve tableau(i)
        ' atribui-se um valor ao novo elemento
        tableau(i)=cdbl(correspondances(i).value)
    Next

    'fim
End Sub




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

    ' calcula-se o número de cotas
    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

    ' calcula-se o quociente familiar e a renda tributável
    Dim revenu, qf
    revenu=0.72*salaire
    qf=revenu/nbParts

    ' calcula-se o imposto
    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

Observações:

  • no arquivo de texto data.txt, os valores podem estar separados por um ou mais espaços, o que impossibilita o uso da função split para extrair os valores da linha. Foi necessário recorrer a uma expressão regular
  • a função getData retorna, além das três tabelas de limites (coeffR, coeffN), um resultado indicando se houve erro ou não. Esse resultado é uma variante de tabela com dois elementos. O primeiro elemento é um código de erro (0 se não houver erro); o segundo, a mensagem de erro, caso tenha ocorrido algum erro.
  • A função getData não verifica a validade dos valores encontrados no arquivo data.txt. Em uma situação real, ela deveria fazer isso.