Programar em C/Gravação e leitura em arquivos

Origem: Wikilivros, livros abertos por um mundo aberto.

<< Bibliotecas Índice Exercícios >>

Índice

[editar] Trabalhando com arquivos

Já vimos como podemos receber e enviar dados para usuário através do teclado e da tela; agora veremos também como ler e gravar dados em arquivos, o que é aliás muito importante ou até essencial em muitas aplicações.

Assim como as funções de entrada/saída padrão (teclado e tela), as funções de entrada/saída em arquivos estão declaradas no cabeçalho stdio.h. Aliás, as funções para manipulação de arquivos são muito semelhantes às usadas para entrada/saída padrão. Como já dissemos na seção sobre a entrada e saída padrões, a manipulação de arquivos também se dá por meio de fluxos (streams).

Na manipulação de um arquivo, há basicamente três etapas que precisam ser realizadas:

  1. abrir o arquivo;
  2. ler e/ou gravar os dados desejados;
  3. fechar o arquivo.

Em C, todas as operações realizadas com arquivos envolvem seu identificador de fluxo, que é uma variável do tipo FILE * (sobre o qual não cabe agora falar). Para declarar um identificador de fluxo, faça como se fosse uma variável normal:

FILE *fp;        // não se esqueça do asterisco!

[editar] Abrindo e fechando um arquivo

Não surpreendentemente, a primeira coisa que se deve fazer para manipular um arquivo é abri-lo. Para isso, usamos a função fopen(). Sua sintaxe é:

FILE *fopen (char *nome_do_arquivo, char *modo_de_acesso);
  • O nome do arquivo deve ser uma string ou com o caminho completo (por exemplo, /usr/share/appname/app.conf ou C:\Documentos\nomes.txt) ou o caminho em relação ao diretório atual (nomes.txt, ../app.conf) do arquivo que se deseja abrir ou criar.
  • O modo de acesso é uma string que contém uma seqüência de caracteres que dizem se o arquivo será aberto para gravação ou leitura. Depois de aberto o arquivo, você só poderá executar os tipos de ação previstos pelo modo de acesso: não poderá ler de um arquivo que foi aberto somente para escrita, por exemplo. Os modos de acesso estão descritos na tabela a seguir.
Modo Significado
r Abre o arquivo somente para leitura. O arquivo deve existir. (O r vem do inglês read, ler)
r+ Abre o arquivo para leitura e escrita. O arquivo deve existir.
w Abre o arquivo somente para escrita no início do arquivo. Apagará o conteúdo do arquivo se ele já existir, criará um arquivo novo se não existir. (O w vem do inglês write, escrever)
w+ Abre o arquivo para escrita e leitura, apagando o conteúdo pré-existente.
a Abre o arquivo para escrita no final do arquivo. Não apaga o conteúdo pré-existente. (O a vem do inglês append, adicionar, apender)
a+ Abre o arquivo para escrita no final do arquivo e leitura.

Em ambientes DOS/Windows, ao ler arquivos binários (por exemplo, programas executáveis ou certos tipos de arquivos de dados), deve-se adicionar o caractere "b" ao final da string de modo (por exemplo, "wb" ou "r+b") para que o arquivo seja lido/gravado corretamente.

Isso é necessário porque no modo texto (o padrão quando não é adicionado o b) ocorrem algumas traduções de caracteres (por exemplo, a terminação de linha "\r\n" é substituída apenas por "\n" na leitura) que poderiam afetar a leitura/gravação dos arquivos binários (indevidamente inserindo ou suprimindo caracteres).

  • O valor de retorno da função fopen() é muito importante! Ele é o identificador do fluxo que você abriu e é só com ele que você conseguirá ler e escrever no arquivo aberto.
  • Se houver um erro na abertura/criação do arquivo, a função retornará o valor NULL. O erro geralmente acontece por duas razões:
    • O arquivo não existe, caso tenha sido requisitado para leitura.
    • O usuário atual não tem permissão para abrir o arquivo com o modo de acesso pedido. Por exemplo, o arquivo é somente-leitura, ou está bloqueado para gravação por outro programa, ou pertence a outro usuário e não tem permissão para ser lido por outros.

Ao terminar de usar um arquivo, você deve fechá-lo. Isso é feito pela função fclose():

int fclose (FILE *fluxo);
  • O único argumento é o identificador do fluxo (retornado por fopen). O valor de retorno indica o sucesso da operação com o valor zero.

[editar] Exemplo

Um pequeno exemplo apenas para ilustrar a abertura e fechamento de arquivos:

#include <stdio.h>

int main()
{
   FILE *fp;
   fp = fopen ("README", "w");
   if (fp == NULL) {
      printf ("Houve um erro ao abrir o arquivo.\n");
      return 1;
   }
   printf ("Arquivo README criado com sucesso.\n");
   fclose (fp);
   return 0;
}

[editar] Arquivos pré-definidos

Na biblioteca padrão do C, existem alguns fluxos pré-definidos que não precisam (nem devem) ser abertos nem fechados:

  • stdin: dispositivo de entrada padrão (geralmente o teclado)
  • stdout: dispositivo de saída padrão (geralmente o vídeo)
  • stderr: dispositivo de saída de erro padrão (geralmente o vídeo)
  • stdaux: dispositivo de saída auxiliar (em muitos sistemas, associado à porta serial)
  • stdprn: dispositivo de impressão padrão (em muitos sistemas, associado à porta paralela)

[editar] Escrevendo em arquivos

Para escrever em arquivos, há quatro funções, das quais três são análogas às usadas para saída padrão:

Saída padrão Arquivos Explicação
putchar fputc Imprime apenas um caractere.
puts fputs Imprime uma string diretamente, sem nenhuma formatação.
printf fprintf Imprime uma string formatada.
N/A fwrite Grava dados binários para um arquivo.

A seguir apresentamos os protótipos dessas funções:

void fputc (int caractere, FILE *fluxo);
void fputs (char *string, FILE *fluxo);
void fprintf (FILE *fluxo, char *formatação, ...);
int fwrite (void *dados, int tamanho_do_elemento, int num_elementos, FILE *fluxo);

[editar] fputc

[editar] fputs

[editar] fprintf

  • Sintaxe quase igual à de printf(); só é necessário adicionar o identificador de fluxo no início.

[editar] fwrite

  • Essa função envolve os conceitos de ponteiro e vetor, que só serão abordados mais tarde.

[editar] Lendo de arquivos

Novamente, há quatro funções, das quais três se assemelham às usadas para a saída padrão:

Saída padrão Arquivos Explicação
getchar fgetc Recebe apenas um caractere.
gets fgets Lê uma string (geralmente uma linha inteira).
scanf fscanf Recebe uma string formatada.
N/A fread Lê dados binários de um arquivo.
int fgetc (FILE *fluxo);
void fgets (char *string, int tamanho, FILE *fluxo);
void fscanf (FILE *fluxo, char *formatação, ...);
int fread (void *dados, int tamanho_do_elemento, int num_elementos, FILE *fluxo);

[editar] fgetc

[editar] fgets

  • Ao chamar a função fgets(), você deve fornecer o ponteiro para a string onde os dados lidos devem ser guardados, além do tamanho máximo dos dados a serem lidos (para que a memória reservada à string não seja ultrapassada).

[editar] fscanf

  • Sintaxe quase igual à de scanf(); só é necessário adicionar o identificador de fluxo no início.

[editar] fread

  • Essa função envolve os conceitos de ponteiro e vetor, que só serão abordados mais tarde.

[editar] Outras funções

Função Explicação
feof Detecta se o final do arquivo já foi atingido
ferror Verifica se a última operação de leitura ou escrita do fluxo foi executada com sucesso
fseek Movimenta o indicador de posição dentro do arquivo de um fluxo especificado
rewind Volta para o começo do arquivo de um fluxo
remove Remove um arquivo especificado


Nuvola apps konsole.png

Esta página é um esboço de informática. Ampliando-a você ajudará a melhorar o Wikilivros.