Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
ARQUIVOS EM C
Existem dois conjuntos de funções de E/S com arquivos na linguagem C. Num primeiro ponto, tem-se a
E/S ANSI (com buffer ou formatada) e, em termos mais específicos, tem-se a E/S UNIX (sem buffer ou
não formatada). Uma ênfase maior é dada ao primeiro conjunto pela portabilidade deste sistema de
entrada e saída com arquivos.
Existem dois tipos possíveis de acesso a arquivos na linguagem C : sequencial (lendo um registro após o
outro) e aleatório (posicionando-se diretamente num determinado registro).
O sistema de arquivos na linguagem C é definido para manipular uma série de dispositivos, tais como
terminais, acionadores de disco e outros. Estes dispositivos são vistos como arquivos lógicos em C,
denominados STREAM (abstração do dispositivo). O dispositivo real é denominado ARQUIVO
(impressora, disco, console e outros). Um STREAM é associado a um ARQUIVO por uma operação de
abertura do arquivo e, a partir da associação, todas as demais operações de escrita e leitura podem ser
realizadas. A Tabela 1 apresenta as principais funções da linguagem C para manipulação de arquivos.
Função Ação
fopen() Abre um arquivo
Fclose () Fecha um arquivo
putc() e fputc() Escreve um caractere em um arquivo
getc() e fgetc() Lê um caractere de um arquivo
fseek() Posiciona em um registro de um arquivo
fprintf() Efetua impressão formatada em um arquivo
fscanf() Efetua leitura formatada em um arquivo
feof() Verifica o final de um arquivo
fwrite() Escreve tipos maiores que 1 byte em um arquivo
fread() Lê tipos maiores que 1 byte de um arquivo
O sistema de entrada e saída do ANSI C é composto por uma série de funções, cujos protótipos estão reunidos em stdio.h .
Todas estas funções trabalham com o conceito de "ponteiro de arquivo". Este não é um tipo propriamente dito, mas uma
definição usando o comando typedef. Esta definição também está no arquivo stdio.h. Podemos declarar um ponteiro de
arquivo da seguinte maneira:
FILE *Arquivo;
Pela declaração anterior, passa a existir uma variável de nome Arquivo, que é ponteiro para um
arquivo. O ponteiro de arquivo une o sistema de E/S a um buffer. O ponteiro não aponta diretamente
para o arquivo em disco, mas contém informações sobre o arquivo, incluindo nome, status (aberto,
fechado e outros) e posição atual sobre o arquivo.
2
1) ABRINDO UM ARQUIVO
A função que abre um arquivo em C é a função fopen(), que devolve o valor NULL (nulo) ou um
ponteiro associado ao arquivo, devendo ser passado para função o nome físico do arquivo e o modo
como este arquivo deve ser aberto. Arquivo = fopen ("texto.txt","w");
Com a instrução acima, está sendo aberto um arquivo de nome "texto.txt", no disco, habilitado
apenas para escrita (w-write). Utilizando-se técnicas de verificação, pode-se codificar a instrução
acima da seguinte maneira:
if ((Arquivo = fopen("texto.txt","w")) == NULL) {
printf("\n Arquivo TEXTO.TXT não pode ser aberto : TECLE ALGO");
getch();
}
Além do modo de escrita, a linguagem C permite o uso de alguns valores padronizados para o modo de
manipulação de arquivos, conforme mostra a Tabela 2
Modo Significado
"r" Abre um arquivo texto para leitura. O arquivo deve existir antes de ser aberto.
Abrir um arquivo texto para gravação. Se o arquivo não existir, ele será criado. Se já existir, o
"w"
conteúdo anterior será destruído.
Abrir um arquivo texto para gravação. Os dados serão adicionados no fim do arquivo ("append"), se
"a"
ele já existir, ou um novo arquivo será criado, no caso de arquivo não existente anteriormente.
"rb" Abre um arquivo binário para leitura. Igual ao modo "r" anterior, só que o arquivo é binário.
"wb" Cria um arquivo binário para escrita, como no modo "w" anterior, só que o arquivo é binário.
"ab" Acrescenta dados binários no fim do arquivo, como no modo "a" anterior, só que o arquivo é binário.
"r+" Abre um arquivo texto para leitura e gravação. O arquivo deve existir e pode ser modificado.
Cria um arquivo texto para leitura e gravação. Se o arquivo existir, o conteúdo anterior será destruído.
"w+"
Se não existir, será criado.
Abre um arquivo texto para gravação e leitura. Os dados serão adicionados no fim do arquivo se ele já
"a+"
existir, ou um novo arquivo será criado, no caso de arquivo não existente anteriormente.
"r+b" Abre um arquivo binário para leitura e escrita. O mesmo que "r+" acima, só que o arquivo é binário.
"w+b" Cria um arquivo binário para leitura e escrita. O mesmo que "w+" acima, só que o arquivo é binário.
Acrescenta dados ou cria uma arquivo binário para leitura e escrita. O mesmo que "a+" acima, só que
"a+b"
o arquivo é binário
Em modo texto, cada caracter (digito, letra, ou caracter especial) ocupa um byte. Ou seja, para gravar o
número 32153, que em memória ocuparia 2 bytes, em arquivo modo texto são necessários 5 bytes. O
modo binário é mais eficiente para guardar números pois ocupa menos espaço.
2) FECHANDO UM ARQUIVO
Existem várias funções em C para a operação de gravação de dados em Arquivos. Vejamos Algumas :
a) putc ou fputc: Grava um único caracter no arquivo
b) fprintf : Grava dados formatados no arquivo, de acordo com o tipo de dados (float, int, ...). Similar
ao printf, porém ao invés de imprimir na tela, grava em arquivo
c) fwrite : Grava um conjunto de dados heterogêneos (struct) no arquivo.
SINTAXE DO PUTC:
Vejamos o exemplo de putc, num programa que simula um editor de texto, bem simples, que grava em
arquivo um texto que vai sendo digitado via teclado até que o usuário finalize com um CTRL+Z
#include <stdio.h>
#include <conio.h>
void main () {
FILE *Arquivo;
char Caractere, Nome[20];
clrscr();
printf("Nome do arquivo? ");
fflush(stdin);
gets(Nome);
Arquivo = fopen (Nome,"w");
if (Arquivo == NULL) {
printf ("Erro abertura do Arquivo : %s. Tecle algo !\n",Nome);
getch();
}
else {
do {
Caractere = getche();
if (Caractere == 13) { \* teclou enter *\
putc('\n',Arquivo); \* grava um \n no arquivo
printf("\n"); \* pular linha na tela pois getche não faz isso com enter */
}
else {
putc(Caractere,Arquivo);
}
} while (Caractere != 26); // CTRL + Z para encerrar
}
fclose(Arquivo);
printf("\n Fim da digitação do texto !" );
getch();
}
Programa 1 – Manipulação de arquivo-texto para escrita
SINTAXE DO GETC:
Vejamos o exemplo de getc, num programa que simula um "mostrador" de texto, bem simples, que lê
arquivo texto já gravado em disco e vai mostrando na tela :
#include <stdio.h>
#include <conio.h>
void main () {
FILE *Arquivo;
char Nome[20];
char Caractere;
clrscr ();
printf ("Nome do arquivo? ");
fflush(stdin);
gets (Nome);
EXERCICIOS :
a) Escreva um programa que faça a cópia de um arquivo origem, gerando um para um arquivo destino
onde todos os caracteres estejam em minúsculo. A função tolower converte um caracter para
minúsculo, está na biblioteca ctype.h e possui a seguinte sintaxe :
a = tolower(b);
A instrução acima converte o caracter da variável b para minúsculo e retorna para a variável a,
onde a e b podem ser a mesma variável.
5
b) Escreva um programa para contar quantas palavras existem num arquivo texto. Lembre-se de
considerar como separador de palavra os caracteres :
'\t' - caracter de tabulação
'\n' – quebra de linha
' ' - espaço em branco
Sintaxe :
• int fprintf(arquivo, "formatos", var1, var2 ...);
fprintf retorna a quantidade de bytes gravadas ou EOF em caso de
erro
No exemplo abaixo, suponha que arqfunc foi aberto com fopen ...
...
FILE *arqfunc;
int idade = 21, tot_bytes;
char sexo = 'M';
float salario = 552.75;
...
tot_bytes = fprintf (arqfunc, "%d %c %f ", idade, sexo,
salario);
No exemplo abaixo, suponha que arqfunc foi aberto com fopen ...
...
FILE *arqfunc;
int idade = 21, totbytes;
char sexo = 'M';
float salario = 552.75;
...
quant_var = fscanf (arqfunc, "%d %c %f ", &idade, &sexo,
*salario);
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main() {
FILE *arqfunc;
int sexo;
int codfunc, idade;
float salario;
if (arqfunc == NULL) {
printf("\nArquivo FUNCIONA.DAD nao pode ser criado.");
printf("\nErro Grave ! Tecle algo !");
getch();
}
else {
clrscr();
do {
printf("\n Digite o codigo do funcionario ou um numero negativo \
para encerrar : ");
scanf("%d", &codfunc);
if (codfunc > 0){
printf("\n Digite o sexo [M ou F] : ");
sexo = getche();
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define LETRAS 60
void main() {
FILE *arqfunc;
char sexo, aux;
int codfunc, idade, i = 0;
float salario;
clrscr();
arqfunc = fopen("FUNCIONA.DAD", "r");
if (arqfunc == NULL) {
printf("\nArquivo FUNCIONA.DAD nao pode ser aberto.");
printf("\nErro Grave ! Tecle algo !");
getch();
}
else {
aux = fscanf(arqfunc, "%d %c %d %f",&codfunc, &sexo, &idade, &salario);
while (aux != EOF) {
i = i + 1;
printf("\n Dados do %d § funcionario : \n ", i);
printf("\n Codigo : %d Sexo : %c", codfunc, sexo);
printf("\n Idade ...: %d Salario : %8.2f", idade, salario);
printf("\n------------------------------------- Tecle algo !");
getch();
aux = fscanf(arqfunc, "%d %c %d %f",&codfunc, &sexo, &idade, &salario);
}
fclose (arqfunc);
printf("\n *** FIM : Tecle algo ! ");
getch();
}
}
Além da manipulação de arquivos do tipo texto, pode-se ler e escrever estruturas maiores que 1 byte,
usando as funções fread() e fwrite(), conforme os protótipos seguintes.
O buffer é um endereço de memória da estrutura de onde deve ser lido ou onde devem ser escritos os
valores (fread() e fwrite(), respectivamente). O tamanhoembytes é um valor numérico
que define o número de bytes da estrutura que deve ser lida/escrita. A quantidade é o número de
estruturas que devem ser lidas ou escritas em cada processo de fread ou fwrite. O
ponteirodearquivo é o ponteiro do arquivo de onde deve ser lida ou escrita uma estrutura.
Normalmente quando trabalhos com arquivos (não texto), utilizamos arquivos de estruturas (struct).
Podemos por exemplo falar num arquivo de CLIENTES, onde cada cliente possui NOME, RG,
ENDERECO E TELEFONE.
9
Na linguagem de ARQUIVOS, cada OCORRÊNCIA de cliente num arquivo é chamado de
REGISTRO e cada informação dentro do REGISTRO do cliente é chamada de CAMPO.
Num arquivo com 10 clientes, dizemos que há 10 registros. No exemplo acima, dizemos que os
campos do REGISTRO de Clientes são : NOME, RG, ENDEREÇO e TELEFONE.
Exemplo :
Exemplos :
#include <stdio.h>
#include <conio.h>
#define LETRAS 50
struct Tcliente {
char situacao; // situacao do registro : excluido ou nao ?
int codigo; // codigo do sujeito
char nomecli[LETRAS]; // nome do sujeito
char fone [15]; // fone do sujeito
char sexo; // sexo
float limite; // limite de credito
};
// prototipos
void Entrada (FILE *);
char ValidaSexo();
char Validaresp();
// =================================================================
void main() {
FILE *cliente;
char verro = 'N';
char arqcli [] = {"CLIENTE.DAD"};
if (verro == 'N') {
Entrada(cliente);
fclose (cliente);
}
10
}
do {
clrscr();
printf("\n Digite o Codigo [Zero encerra] : " );
scanf("%d", &Vcli.codigo);
if (Vcli.codigo != 0) {
printf(" \n Digite o nome : ");
fflush(stdin);
gets(Vcli.nomecli);
Vcli.sexo = ValidaSexo();
printf(" \n Digite o Fone : " );
gets(Vcli.fone);
printf(" \n Digite o Limite de Credito do cliente : ");
scanf("%f", &Vcli.limite);
vresp = Validaresp();
if (vresp == 'S') {
retorno = fwrite (&Vcli, sizeof(struct Tcliente) ,1,cliente);
// fwrite retorna a quantidade de itens gravados (NAO BYTES)
if (retorno == 1) {
printf(" \n Gravacao ok ! ");
getch();
}
else {
printf (" \n Problemas : Gravacao nao efetuada !!!" );
getch();
}
}
}
} while (Vcli.codigo != 0);
}
// validar o sexo
char ValidaSexo() {
char vsexo;
do {
printf(" \n Digite o Sexo [M ou F] : " );
vsexo = getche();
} while (vsexo != 'F' && vsexo != 'M');
return vsexo;
}
// validar a respostar
// validar o sexo
char Validaresp() {
char vresp;
do {
printf(" \n Confirma Inclusao [S ou N] ? " );
vresp = getche();
} while (vresp != 'S' && vresp != 'N');
return vresp;
}
11
O PROGRAMA ABAIXO ABRE UM ARQUIVO E IMPRIME OS DADOS NA TELA
#include <stdio.h>
#include <conio.h>
#define LETRAS 50
struct Tcliente {
char situacao; // situacao do registro : excluido ou nao ?
int codigo; // codigo do sujeito
char nomecli[LETRAS]; // nome do sujeito
char fone [15]; // fone do sujeito
char sexo; // sexo
float limite; // limite de credito
};
// prototipos
void Le_Imprime (FILE *);
void main() {
FILE *cliente;
char verro = 'N';
char arqcli [] = {"CLIENTE.DAD"};
if (verro == 'N') {
Le_Imprime(cliente);
fclose (cliente);
}
}
printf(" \n\n %d clientes cadastrados ", cont);
getch();
}