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:
- abrir o arquivo;
- ler e/ou gravar os dados desejados;
- 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 é:
- 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():
- 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:
[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. |
[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 |
|
Esta página é um esboço de informática. Ampliando-a você ajudará a melhorar o Wikilivros. |