Вы находитесь на странице: 1из 10

1

ARQUIVOS EM C
Existem dois conjuntos de funes 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 especficos, tem-se a E/S UNIX (sem buffer ou no formatada). Uma nfase maior dada ao primeiro conjunto pela portabilidade deste sistema de entrada e sada com arquivos. Existem dois tipos possveis de acesso a arquivos na linguagem C : sequencial (lendo um registro aps o outro) e aleatrio (posicionando-se diretamente num determinado registro). O sistema de arquivos na linguagem C definido para manipular uma srie de dispositivos, tais como terminais, acionadores de disco e outros. Estes dispositivos so vistos como arquivos lgicos em C, denominados STREAM (abstrao do dispositivo). O dispositivo real denominado ARQUIVO (impressora, disco, console e outros). Um STREAM associado a um ARQUIVO por uma operao de abertura do arquivo e, a partir da associao, todas as demais operaes de escrita e leitura podem ser realizadas. A Tabela 1 apresenta as principais funes da linguagem C para manipulao de arquivos. Funo Ao Abre um arquivo Fecha um arquivo Escreve um caractere em um arquivo L um caractere de um arquivo Posiciona em um registro de um arquivo Efetua impresso formatada em um arquivo Efetua leitura formatada em um arquivo Verifica o final de um arquivo Escreve tipos maiores que 1 byte em um arquivo L tipos maiores que 1 byte de um arquivo Escreve uma cadeia de caracteres em um arquivo L uma cadeia de caracteres em um arquivo Posiciona o cursor no incio do arquivo Apaga um arquivo Altera o nome de um arquivo

fopen() fclose () fputc() fgetc() fseek() fprintf() fscanf() feof() fwrite() fread() fputs() fgets() rewind() remove() rename()

Tabela 1 - Funes do padro ANSI para manipulao de arquivos


O sistema de entrada e sada do ANSI C composto por uma srie de funes, cujos prottipos esto reunidos em stdio.h . Todas estas funes trabalham com o conceito de "ponteiro de arquivo". Este no um tipo propriamente dito, mas uma definio usando o comando typedef. Esta definio tambm est no arquivo stdio.h. Podemos declarar um ponteiro de arquivo da seguinte maneira:

FILE *Arquivo;
Pela declarao anterior, passa a existir uma varivel de nome Arquivo, que ponteiro para um arquivo. O ponteiro de arquivo une o sistema de E/S a um buffer. O ponteiro no aponta diretamente para o arquivo em disco, mas contm informaes sobre o arquivo, incluindo nome, status (aberto, fechado e outros) e posio atual sobre o arquivo.

1) ABRINDO UM ARQUIVO
A funo que abre um arquivo em C a funo fopen(), que devolve o valor NULL (nulo) ou um ponteiro associado ao arquivo, devendo ser passado para funo o nome fsico do arquivo e o modo como este arquivo deve ser aberto. Arquivo = fopen ("texto.txt","w");

Com a instruo acima, est sendo aberto um arquivo de nome "texto.txt", no disco, habilitado apenas para escrita (w-write). Utilizando-se tcnicas de verificao, pode-se codificar a instruo acima da seguinte maneira:
if ((Arquivo = fopen("texto.txt","w")) == NULL) { printf("\n Arquivo TEXTO.TXT no pode ser aberto : TECLE ALGO"); getch(); }

Alm do modo de escrita, a linguagem C permite o uso de alguns valores padronizados para o modo de manipulao de arquivos, conforme mostra a Tabela 2
Modo "r" Significado

Abre um arquivo texto para leitura. O arquivo deve existir antes de ser aberto. Abrir um arquivo texto para gravao. Se o arquivo no existir, ele ser criado. Se j existir, o "w" contedo anterior ser destrudo. Abrir um arquivo texto para gravao. Os dados sero adicionados no fim do arquivo ("append"), se "a" ele j existir, ou um novo arquivo ser criado, no caso de arquivo no existente anteriormente. "rb" Abre um arquivo binrio para leitura. Igual ao modo "r" anterior, s que o arquivo binrio. "wb" Cria um arquivo binrio para escrita, como no modo "w" anterior, s que o arquivo binrio. "ab" Acrescenta dados binrios no fim do arquivo, como no modo "a" anterior, s que o arquivo binrio. "r+" Abre um arquivo texto para leitura e gravao. O arquivo deve existir e pode ser modificado. Cria um arquivo texto para leitura e gravao. Se o arquivo existir, o contedo anterior ser destrudo. "w+" Se no existir, ser criado. Abre um arquivo texto para gravao e leitura. Os dados sero adicionados no fim do arquivo se ele "a+" j existir, ou um novo arquivo ser criado, no caso de arquivo no existente anteriormente. "r+b" Abre um arquivo binrio para leitura e escrita. O mesmo que "r+" acima, s que o arquivo binrio. "w+b" Cria um arquivo binrio para leitura e escrita. O mesmo que "w+" acima, s que o arquivo binrio. Acrescenta dados ou cria uma arquivo binrio para leitura e escrita. O mesmo que "a+" acima, s que "a+b" o arquivo binrio

Tabela 2 - Modos para manipulao de arquivos MODO BINRIO X MODO TEXTO Em modo texto, cada caracter (digito, letra, ou caracter especial) ocupa um byte. Ou seja, para gravar o nmero 32153, que em memria ocuparia 2 bytes, em arquivo modo texto so necessrios 5 bytes. O modo binrio mais eficiente para guardar nmeros pois ocupa menos espao.

2) FECHANDO UM ARQUIVO
Para o esvaziamento do buffer de um arquivo utilizada a funo fclose(), que associa-se diretamente ao nome lgico do arquivo (STREAM).

fclose (Arquivo);

3) GRAVANDO DADOS DADOS EM ARQUIVOS:


Existem vrias funes em C para a operao de gravao 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, porm ao invs de imprimir na tela, grava em arquivo c) fwrite : Grava um conjunto de dados heterogneos (struct) no arquivo. SINTAXE DO PUTC: putc (caracter, arquivo); /* Grava o contedo da varivel caracter no "arquivo" */

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 usurio 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 no faz isso com } else { putc(Caractere,Arquivo); } } while (Caractere != 26); // CTRL + Z para encerrar } fclose(Arquivo); printf("\n Fim da digitao do texto !" ); getch(); }
Programa 1 Manipulao de arquivo-texto para escrita OBS : Mais adiante veremos a sintaxe e o exemplo de uso de fprintf e fwrite

enter */

4) LENDO DADOS EM ARQUIVOS:


Existem vrias funes em C para a operao de leitura de dados de Arquivos. Vejamos Algumas : a) getc ou fgetc: L um nico caracter do arquivo b) fscanf : L dados formatados no arquivo, de acordo com o tipo de dados (float, int, ...). Similar ao scanf, porm ao invs de ler do "teclado" l de um arquivo c) fread : L um conjunto de dados heterogneos (struct) do arquivo. SINTAXE DO GETC: Caracter = getc (arquivo); /* L um caracter do "arquivo" e retorna para a varivel Caracter */

getc retorna EOF caso encontre o fim-de-arquivo ou em caso de erro na leitura 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); Arquivo = fopen (Nome,"r"); if (Arquivo == NULL) { printf ("Erro abertura do Arquivo : %s. Tecle algo !\n",Nome); getch(); } else { Caractere = getc(Arquivo); while (Caractere != EOF) { printf("%c", Caractere); Caractere = getc(Arquivo); } fclose (Arquivo); fprintf("\n *** fim de texto *** Tecle algo !") getch (); } }
Programa 2 Manipulao de arquivo-texto para leitura OBS : Mais adiante veremos a sintaxe e o exemplo de uso de fscanf e fread

EXERCICIOS : a) Escreva um programa que faa a cpia de um arquivo origem, gerando um para um arquivo destino onde todos os caracteres estejam em minsculo. A funo tolower converte um caracter para minsculo, est na biblioteca ctype.h e possui a seguinte sintaxe : a = tolower(b); A instruo acima converte o caracter da varivel b para minsculo e retorna para a varivel a, onde a e b podem ser a mesma varivel. 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 tabulao '\n' quebra de linha ' ' - espao em branco

AS OUTRAS FUNES DE LEITURA E GRAVAO EM ARQUIVO

A) LENDO E GRAVANDO DADOS "FORMATADOS" com fscanf e fprintf 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); obs. : Os formatos devem ser separados por espaos em branco

int fscanf(arquivo, "formatos", &var1, &var2 ...);


fscanf retorna a quantidade variveis lidas com sucesso 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);

obs. : Os formatos devem ser separados por espaos em branco


OBS : O uso de fscanf no recomendada para string pois, da mesma forma que scanf com %s, fscanf tambm encerra e leitura ao encontrar um espao em branco. Em outras palavras, se no arquivo estiver gravado um nome "JOSE DA SILVA SOUZA" o fscanf ler apenas para o formato %s a palavra "JOSE". Como alternativa poderamos usar a funo fgets, mas esta exige que se saiba a quantidade de caracteres a ser lido a cada momento. Resolveremos este problema com fread e fwrite. De qualquer forma, vejamos exemplos de programas com o uso de fprintf e fscanf O programa abaixo, obtm o Cdigo do Funcionrio, o sexo, a idade e o salrio de N pessoas, a partir do teclado, e grava os dados num arquivo, utilizando fprintf O Critrio de terminao quando o usurio digita um cdigo do funcionrio negativo Por questes de simplificao no estamos verificando se o arquivo foi aberto com sucesso, nem se o sexo vlido ou no ...

6 /* programa exemplo com fprintf */ #include <stdio.h> #include <conio.h> #include <string.h> void main() { FILE *arqfunc; int sexo; int codfunc, idade; float salario; arqfunc = fopen("FUNCIONA.DAD", "w"); 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(); printf("\n Digite a idade : "); scanf("%d", &idade); printf("\n Digite o salario : "); scanf("%f", &salario); /* a instrucao abaixo grava os dados no arquivo */ fprintf(arqfunc, "%d %c %d %f ", codfunc, sexo, idade, salario); } } while ( codfunc > 0); fclose (arqfunc); } }

O programa abaixo l o arquivo gravado com o programa anterior, utilizando fscanf e mostra os dados na tela Veja que deve-se usar a mesma seqncia de leitura que se usou para gravar : O Primeiro nome, depois o sexo, a idade e o salrio. Veja ainda que o nome lido com fgets devido ao problema j exposto anteriormente sobre o fscanf com %s
/* programa exemplo com fscanf #include <stdio.h> #include <conio.h> #include <string.h> #define LETRAS 60 void main() { FILE *arqfunc; char sexo, aux; int codfunc, idade, float salario;

i = 0;

7 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 getch(); } }

: Tecle algo ! ");

B) LENDO E GRAVANDO ESTRUTURAS Alm da manipulao de arquivos do tipo texto, pode-se ler e escrever estruturas maiores que 1 byte, usando as funes fread() e fwrite(), conforme os prottipos seguintes.

fread (buffer, tamanhoembytes, quantidade, ponteirodearquivo) fwrite (buffer, tamanhoembytes, quantidade, ponteirodearquivo)
O buffer um endereo de memria da estrutura de onde deve ser lido ou onde devem ser escritos os valores (fread() e fwrite(), respectivamente). O tamanhoembytes um valor numrico que define o nmero de bytes da estrutura que deve ser lida/escrita. A quantidade o nmero 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 (no texto), utilizamos arquivos de estruturas (struct). Podemos por exemplo falar num arquivo de CLIENTES, onde cada cliente possui NOME, RG, ENDERECO E TELEFONE. Na linguagem de ARQUIVOS, cada OCORRNCIA de cliente num arquivo chamado de REGISTRO e cada informao 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 so : NOME, RG, ENDEREO e TELEFONE.

OBS. : A funo sizeof retorna a quantidade de bytes de um determinado tipo ou varivel Exemplo :
sizeof(int) retorna 2 de acordo com o tipo de mquina

sizeof(struct cliente) retorna a somatria de bytes da struct cliente

Exemplos :

O PROGRAMA ABAIXO CRIA UM ARQUIVO E GRAVA OS DADOS NESTE ARQUIVO

#include <stdio.h> #include <conio.h> #define LETRAS 50 struct Tcliente { char situacao; int codigo; char nomecli[LETRAS]; char fone [15]; char sexo; float limite; }; // prototipos void Entrada (FILE *); char ValidaSexo(); char Validaresp(); // ================================================================= void main() { FILE *cliente; char verro = 'N'; char arqcli [] = {"CLIENTE.DAD"}; cliente = fopen(arqcli, "rb+"); if (cliente == NULL) { printf(" \n Arquivo %s Nao existe : Tecle algo para criar agora ! ", arqcli); getch(); if ((cliente = fopen(arqcli, "wb+")) == NULL) { verro = 'S'; printf(" \n Erro grave ! Nao consigo criar o arquivo %s !!!", arqcli); getch(); } } if (verro == 'N') { Entrada(cliente); fclose (cliente); } } // entrada de dados gravando direto em arquivo void Entrada (FILE * cliente) { int retorno; struct Tcliente Vcli; char vresp; 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);

// // // // // //

situacao do registro : excluido codigo do sujeito nome do sujeito fone do sujeito sexo limite de credito

ou nao ?

9 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; }

10

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; int codigo; char nomecli[LETRAS]; char fone [15]; char sexo; float limite; }; // prototipos void Le_Imprime (FILE *); void main() { FILE *cliente; char verro = 'N'; char arqcli [] = {"CLIENTE.DAD"}; if ((cliente = fopen(arqcli, "rb")) == NULL) { verro = 'S'; printf(" \n Erro Grave : Arquivo Nao existe !"); getch(); } if (verro == 'N') { Le_Imprime(cliente); fclose (cliente); } }

// // // // // //

situacao do registro : excluido codigo do sujeito nome do sujeito fone do sujeito sexo limite de credito

ou nao ?

// Le dados de um arquivo e imprime na Tela void Le_Imprime (FILE * cliente) { int retorno, cont = 0; struct Tcliente Vcli; retorno = fread(&Vcli, sizeof(struct Tcliente), 1, cliente); // fread retorna a quantidade de itens retornados ... clrscr(); while ( retorno == 1) { cont++; printf("\n\n DADOS DO CLIENTE %d \n", cont); printf("\n Codigo : %d", Vcli.codigo); printf("\n Nome ..: %s", Vcli.nomecli); printf("\n Sexo ..: %c", Vcli.sexo); printf("\n Fone ..: %s", Vcli.fone); printf("\n Limite : %.2f", Vcli.limite); retorno = fread(&Vcli, sizeof(struct Tcliente), 1, cliente); } printf(" \n\n %d clientes cadastrados ", cont); getch(); }

Вам также может понравиться