Aula 20: Ficheiros

 
Traduzido por Ana Paula Costa

Saída para ficheiros

Hoje vamos aprender como ler de ficheiros e como escrever para ficheiros. Como exemplo vamos apenas aprender como ler e escrever ficheiros de texto, ficheiros em que a informação é armazenada em formato ASCII. Estes ficheiros diferem do formato binário porque também podem ser legíveis para os humanos. Quando escrevemos os nossos programas nas aulas práticas temos utilizado ficheiros de texto.
Estes ficheiros podem ser colocados em disquetes, discos rígidos, ou até mesmo CD-ROMs (caso em que podem - claro - ser apenas lidos e não escritos).

Palavras chave

As seguintes palavras chave estão relacionadas com o acesso a ficheiros:
 


 FILE
 fopen()
 fclose()
 fscanf()
 fprintf() 
 feof()
 fputs() 
 fgets()
 fputc()
 fgetc()
Elas estão definidas na biblioteca <stdio.h>, que deve portanto ser incluída no início do programa.

Declarar uma variável para acesso a um ficheiro:

Antes de se poder abrir um ficheiro e ter acesso a ele (seja para ler ou para escrever) temos que declarar um "handle" para esse ficheiro. O "handle" é uma variável que armazena informação sobre o estado do ficheiro. Em C podemos declarar um ficheiro de texto da seguinte forma:
 


 FILE *filehandle

Com filehandle a variável que irá armazenar o ponteiro para a informação. Isto NÃO é igual ao nome do ficheiro, como iremos ver. Esta declaração deve ser feita no mesmo local das outras variáveis.
Exemplo:
  FILE *f;
Isto cria f um ponteiro para um handle de ficheiro.
Só a título de curiosidade, não é preciso saber isto, o tipo de variável FILE está definido como
typedef struct{
  short          level;
  unsigned       flags;
  char           fd;
  unsigned char  hold;
  short          bsize;
  unsigned char *buffer, *curp;
  unsigned       istemp;
  short          token;
} FILE;
Para mais informação, ver a ajuda do compilador.


Abrir um ficheiro

No programa abrimos o ficheiro com a função fopen() pertencente a <stdio.h>
 

fopen()
diminutivo de "file open". Abre um ficheiro. 
definição da função:   FILE *fopen(const char *filename, const char *mode)
abre um ficheiro. Retorna 0 se não for bem sucedida.

fopen() retorna um ponteiro para um FILE (ao qual podemos atribuir a nossa variável do tipo ponteiro-FILE).
fopen()  recebe dois parâmetros, ambos strings (pointeiros para char). O primeiro é o nome do ficheiro e o segundo é a forma como deve ser aberto, ("r") para leitura, ("w") para escrita, ou ("a") para acrescentar ao final do ficheiro.
Exemplos:
Para abrir um ficheiro chamado "OLA.TXT" para leitura usamos
  FILE *f;
  f = fopen("OLA.TXT", "r");
Para abrir um ficheiro chamado "output.asc" para escrita usamos
  FILE *f;
  f = fopen("output.asc", "w");



 

Ler e Escrever

Ler de um ficheiro e escrever para um ficheiro é feito exactamente da mesma forma do que ler e escrever para o ecrãn, com a única diferença que se utiliza a função fscanf() em vez de scanf() para ler e fprintf() em vez de printf() para escrever. O primeiro parâmetro destas funções tem que ser o handle do ficheiro (por exemplo f)
 

fscanf()
diminutivo de "file scan fornatted". input a partir do ficheiro 
definição da função:   int fscanf(FILE *stream, const char *format, ....)
obtém input formatado do ficheiro

 

fprintf()
diminutivo de "file print formatted". Output formatado para o ficheiro 
definição da função:   int fprintf(FILE *stream, const char *format, ...)
o resultado vai para um ficheiro . Retorna o número de caracteres escritos, EOF se falhar.

De notar que só podemos usar instruções fscanf para ficheiros que tenham sido previamente abertos para leitura ("r") e fprintf é para ser utilizada apenas com ficheiros que tenham sido abertos para escrita ("w"). Exemplos:
  fprintf(f, "%f", r);
  fscanf(f, "%d", opcao);
 
 



Lê uma variável com o teclado
Lê uma variável do ficheiro


Escreve uma variável para o ecrãn
Escreve uma variável para o ficheiro

Fechar o ficheiro

Quando já não necessitamos do ficheiro temos que fechá-lo. Especialmente para ficheiro de output. Se nos esquecemos de fechar o ficheiro antes de terminar o programa, provavelmente haverá informação que não será escrita no ficheiro (o "buffer" não será esvaziado). Para fechar o ficheiro utilizamos fclose().
 

fclose()
diminutivo de "file close". Fecha um ficheiro. 
definição da função:   int fclose(FILE *stream)
fecha um ficheiro. Retorna 0 se tiver sucesso.

por exemplo:
  fclose(f);


Sumário

Entrada e saída de/para ficheiros consiste dos seguintes passos:


Testar Fim-do-ficheiro (End-of-file)

A seguinte instrução pode ser útil
feof(filehandle): Retorna verdadeiro se estamos a ler o fim do ficheiro.
eof significa end-of-file (fim-do-ficheiro)

Exemplo:
  while (!eof(f))
  {
    fscanf("%s", s);
  }
que irá ler do ficheiro até que seja encontrado o fim do ficheiro.


Exemplos



código  ecrãn  ficheiro TEST.TXT
depois de correr o programa
/* With File Output */
#include <stdio.h>

FILE *f;
char s[100];
int i;

void main()
{
  printf("Name of File:");
  scanf("%s", s);
  f = fopen(s, "w");
  for (i=1; i<=10; i++)
    fprintf(f, "%d Hello", i);
  fclose(f);
}

Name of File:
TEST.TXT
1 Hello
2 Hello
3 Hello
4 Hello
5 Hello
6 Hello
7 Hello
8 Hello
9 Hello
10 Hello

 

código  ecrãn  ficheiro TEST.TXT antes
de correr o programa
/* With File Input */
 #include <stdio.h>

 FILE *f;
 char s[100];
 int i;

 void main()
 {
   printf("Name of File:");
   scanf("%s", s);
   f = fopen(s, "r");
   while (!feof(f))
    {
      fscanf(f, "%s", s);
      printf("%s\n", s);
    }
   fclose(f);
 }
 

Name of File:
TEST.TXT
1
Hello
2
Hello
3
Hello
4
Hello
5
Hello
6
Hello
7
Hello
8
Hello
9
Hello
10
Hello
1 Hello
2 Hello
3 Hello
4 Hello
5 Hello
6 Hello
7 Hello
8 Hello
9 Hello
10 Hello
O resultado provavelmente não é aquele que gostaríamos de ter obtido. Talvez devêssemos utilizar a função fgets() para ler as strings. Ver em baixo.

Outras funções para ficheiros

Outras funções para ficheiros bastante úteis são
 

fgets()
diminutivo de "file get string". Lê uma string do ficheiro. 
definição da função:   char *fgets(char s1, int n, FILE *stream)
lê uma string do ficheiro até eol (end of line), eof (end of file) ou o máximo de n-1 caracteres serem lidos

 

fgetc()
diminutivo de "file get char". Lê um caracter do ficheiro. 
definição da função:   int fgetc(FILE *stream)
lê um único caracter do ficheiro. Retorna o valor do caracter se bem sucedida.

 

fputs()
diminutivo de "file put string". Escreve uma string para o ficheiro. 
definição da função:   int fputs(const char s1, FILE *stream)
escreve uma string para o ficheiro. Retorna 0 se bem sucedida.

 

fputc()
diminutivo de "file pu char". Escreve um caracter para o ficheiro. 
definição da função:   int fputc(char *s1, FILE *stream)
escreve um único caracter para o ficheiro. Retorna o valor do caracter se bem sucedida.


Teste Rápido:
Para testar os conhecimentos sobre o que aprendeu nesta aula, prima aqui para fazer um teste on-line. De notar que este Não é o formato que será utilizado no teste final!

Peter Stallinga. Universidade do Algarve, 17 December 2002