Buscar

capitulo 15

Prévia do material em texto

2/6/2005 (c) Dept. Informática - PUC-Rio 1
Estruturas de Dados 
Módulo 15 - Arquivos
2/6/2005 (c) Dept. Informática - PUC-Rio 2
Referências
Waldemar Celes, Renato Cerqueira, José Lucas Rangel, 
Introdução a Estruturas de Dados, Editora Campus 
(2004)
Capítulo 15 – Arquivos
2/6/2005 (c) Dept. Informática - PUC-Rio 3
Tópicos
• Introdução
• Funções para abrir e fechar arquivos
• Arquivos em modo texto
• Estruturação de dados em arquivos texto
• Arquivos em modo binário
2/6/2005 (c) Dept. Informática - PUC-Rio 4
Introdução
• Serviços oferecidos pelos sistema operacional (SO):
Arquivo
Disco
Buffer
Memória
Programa
mmMm
Mm M
2/6/2005 (c) Dept. Informática - PUC-Rio 5
Introdução
• Serviços oferecidos pelos sistema operacional (SO):
– Abertura de arquivo: 
• SO encontra o arquivo com o nome dado e prepara o buffer na memória
– Leitura do arquivo: 
• SO recupera o trecho solicitado do arquivo
• SO obtém os dados, na sua totalidade ou em parte, do buffer 
– Escrita no arquivo: 
• SO acrescenta ou altera o conteúdo do arquivo
• SO altera dados no buffer para posteriormente transferi-los para disco
– Fechamento de arquivo: 
• SO transfere todos os dados do buffer para disco
• SO libera área do buffer 
2/6/2005 (c) Dept. Informática - PUC-Rio 6
Funções para abrir e fechar arquivos
FILE* fopen (char* nome_arquivo, char* modo);
• valor de retorno:
– ponteiro para o tipo FILE
• tipo FILE definido pela biblioteca padrão para representar arquivos
• todas as operações subseqüentes no arquivo receberão 
este endereço como parâmetro de entrada
– NULL, se o arquivo não puder ser aberto
2/6/2005 (c) Dept. Informática - PUC-Rio 7
Funções para abrir e fechar arquivos
FILE* fopen (char* nome_arquivo, char* modo);
• parâmetro nome_arquivo
– nome do arquivo a ser aberto
– pode ser relativo ao diretório de trabalho do programa, ou 
– pode ser absoluto, incluindo os diretórios, desde o diretório raiz 
2/6/2005 (c) Dept. Informática - PUC-Rio 8
Funções para abrir e fechar arquivos
FILE* fopen (char* nome_arquivo, char* modo);
• parâmetro modo
r leitura (read)
w escrita (write)
a acréscimo ao final do arquivo (append)
t texto (text)
b binário (binary)
r+ leitura e escrita num arquivo já existente
w+ leitura e escrita num novo arquivo 
2/6/2005 (c) Dept. Informática - PUC-Rio 9
Funções para abrir e fechar arquivos
• Comentários sobre os modo de abertura:
– modos b e t:
• podem ser combinados com os demais 
– modo w:
• se o arquivo não existe, um novo é criado, inicialmente vazio
• se o arquivo já existe, ele é destruído e um novo é criado, inicialmente vazio
• fopen retorna NULL se o programa não tem acesso de escrita ao diretório 
– modo a:
• arquivo é preservado e novos dados podem ser escritos no final do arquivo 
– modo r:
• arquivo já deve existir, caso contrário a fopen falha e retorna NULL
2/6/2005 (c) Dept. Informática - PUC-Rio 10
Funções para abrir e fechar arquivos
• Exemplo:
– solicita abertura de entrada.txt para leitura em modo texto
– testa se a abertura do arquivo foi realizada com sucesso
...
FILE* fp;
fp = fopen("entrada.txt","rt");
if (fp == NULL) {
printf("Erro na abertura do arquivo!\n");
exit(1);
}
...
2/6/2005 (c) Dept. Informática - PUC-Rio 11
Funções para abrir e fechar arquivos
int fclose (FILE* fp);
• parâmetro:
– ponteiro do arquivo que se deseja fechar
• valor de retorno:
– a constante 0, se o arquivo for fechado com sucesso
– a constante EOF (definida na biblioteca), se houve erro 
2/6/2005 (c) Dept. Informática - PUC-Rio 12
Arquivos em modo texto
• Leitura de arquivos:
– cada arquivo possui um cursor indicando a posição corrente
– quando o arquivo é aberto para leitura:
• o cursor é posicionado no início do arquivo
– a cada leitura:
• o dado lido é sempre aquele apontado pelo cursor do arquivo
• o cursor avança e passa a apontar para a posição imediatamente 
após o dado lido
– a próxima leitura captura o próximo dado do arquivo 
2/6/2005 (c) Dept. Informática - PUC-Rio 13
Arquivos em modo texto
• Funções para ler dados de arquivos em modo texto:
int fscanf (FILE* fp, char* formato, ...);
int fgetc (FILE* fp);
char* fgets (char* s, int n, FILE* fp);
2/6/2005 (c) Dept. Informática - PUC-Rio 14
Arquivos em modo texto
int fscanf (FILE* fp, char* formato, ...);
• parâmetros: 
– ponteiro para o arquivo do qual os dados serão lidos
– formato e lista de endereços de variáveis que armazenarão os 
valores lidos (como na função scanf)
• valor de retorno:
– número de dados lidos com sucesso 
• definição:
– transfere dados para a memória
– avança o cursor para o próximo dado
2/6/2005 (c) Dept. Informática - PUC-Rio 15
Arquivos em modo texto
int fgetc (FILE* fp);
• parâmetro:
– ponteiro para o arquivo do qual os dados serão lidos
• valor de retorno:
– código do caractere lido 
– constante EOF (end of file), se o fim do arquivo for alcançado
• definição:
– captura o próximo caractere do arquivo
– avança o cursor para o próximo caractere
2/6/2005 (c) Dept. Informática - PUC-Rio 16
Arquivos em modo texto
char* fgets (char* s, int n, FILE* fp);
• parâmetros:
– cadeia de caracteres que armazenará o conteúdo lido do arquivo
– número máximo de caracteres que deve ser lido
– ponteiro para o arquivo do qual os dados serão lidos
• valor de retorno:
– ponteiro da própria cadeia de caracteres passada como parâmetro
– NULL, em caso de erro de leitura (ex: quando alcançar o final do arquivo)
• definição:
– lê uma seqüência de caracteres, até que um caractere '\n' seja encontrado ou 
que o máximo de caracteres especificado seja alcançado
– especificação do número máximo de caracteres evita invasão de memória 
quando a linha do arquivo for maior do que suposto
2/6/2005 (c) Dept. Informática - PUC-Rio 17
Arquivos em modo texto
• Funções para escrever dados em arquivos em modo 
texto:
int fprintf(FILE* fp, char* formato, ...);
int fputc (int c, FILE* fp);
2/6/2005 (c) Dept. Informática - PUC-Rio 18
Arquivos em modo texto
int fprintf(FILE* fp, char* formato, ...);
• parâmetro:
– ponteiro para o arquivo no qual o dado será salvo
– formato e lista de endereços de variáveis que fornecerão os 
dados a serem escritos no arquivo (como na função printf)
• valor de retorno:
– representa o número de bytes escritos no arquivo
• definição:
– (similar à função printf)
2/6/2005 (c) Dept. Informática - PUC-Rio 19
Arquivos em modo texto
int fputc (int c, FILE* fp);
• parâmetros:
– código do caractere a ser escrito (salvo)
– ponteiro para o arquivo no qual o caractere será escrito
• valor de retorno:
– o próprio caractere escrito
– EOF, se ocorrer um erro na escrita
• definição:
– escreve um caractere no arquivo
2/6/2005 (c) Dept. Informática - PUC-Rio 20
Estruturação de dados em arquivos textos
• Formas para representar e acessar dados em arquivos: 
– caractere a caractere
– linha a linha
– usando palavras-chaves
2/6/2005 (c) Dept. Informática - PUC-Rio 21
Estruturação de dados em arquivos textos
• Exemplo de acesso caractere a caractere:
– programa para contar o número de linhas de um arquivo 
(de nome “entrada.txt”)
• leia, caractere a caractere, todo o conteúdo do arquivo, 
contando o número de ocorrências do caractere '\n‘
(que indica mudança de linha)
2/6/2005 (c) Dept. Informática - PUC-Rio 22
/* Conta número de linhas de um arquivo */
#include <stdio.h>
int main (void)
{
int c;
int nlinhas = 0; /* contador do número de linhas */
FILE *fp;
/* abre arquivo para leitura */
fp = fopen("entrada.txt","rt");
if (fp==NULL) {
printf("Não foi possivel abrir arquivo.\n");return 1;
}
2/6/2005 (c) Dept. Informática - PUC-Rio 23
/* lê caractere a caractere */
while ((c = fgetc(fp)) != EOF) 
{
if (c == '\n')
nlinhas++;
}
/* fecha arquivo */
fclose(fp);
/* exibe resultado na tela */
printf("Numero de linhas = %d\n", nlinhas);
return 0;
}
2/6/2005 (c) Dept. Informática - PUC-Rio 24
Estruturação de dados em arquivos textos
• Exemplo de acesso caractere a caractere:
– programa para:
• ler o conteúdo do arquivo
• criar um arquivo com o mesmo conteúdo, 
mas com todas as letras minúsculas convertidas para maiúsculas
– nomes dos arquivos fornecidos, via teclado, pelo usuário 
2/6/2005 (c) Dept. Informática - PUC-Rio 25
/* Converte arquivo para maiúsculas */
#include <stdio.h>
#include <ctype.h> /* função toupper : converte para maiúsculas */
int main (void)
{
int c;
char entrada[121]; /* armazena nome do arquivo de entrada */
char saida[121]; /* armazena nome do arquivo de saída */
FILE* e; /* ponteiro do arquivo de entrada */
FILE* s; /* ponteiro do arquivo de saída */
/* pede ao usuário os nomes dos arquivos */
printf("Digite o nome do arquivo de entrada: ");
scanf("%120s",entrada);
printf("Digite o nome do arquivo de saida: ");
scanf("%120s",saida);
2/6/2005 (c) Dept. Informática - PUC-Rio 26
/* abre arquivos para leitura e para escrita */
e = fopen(entrada,"rt");
if (e == NULL) {
printf("Não foi possível abrir arquivo de entrada.\n");
return 1;
}
s = fopen(saida,"wt");
if (s == NULL) {
printf("Não foi possível abrir arquivo de saida.\n");
fclose(e);
return 1;
}
/* lê da entrada e escreve na saída */
while ((c = fgetc(e)) != EOF)
fputc(toupper(c),s);
/* fecha arquivos */
fclose(e);
fclose(s);
return 0;
}
2/6/2005 (c) Dept. Informática - PUC-Rio 27
Estruturação de dados em arquivos textos
• Exemplo de acesso linha a linha:
– programa para procurar a ocorrência de uma sub-cadeia de 
caracteres dentro de um arquivo: 
• se a sub-cadeia for encontrada, 
retorne o número da linha da primeira ocorrência
– leia, linha a linha, o conteúdo do arquivo, contanto o número da linha
– para cada linha, verifique a ocorrência da sub-cadeia, 
interrompendo a leitura em caso afirmativo
– função strstr
• procura a ocorrência de uma sub-cadeia 
numa cadeia de caracteres maior
• retorna o endereço da primeira ocorrência ou 
NULL, se a sub-cadeia não for encontrada
2/6/2005 (c) Dept. Informática - PUC-Rio 28
/* Procura ocorrência de sub-cadeia em arquivo com linhas de 121 posições*/
#include <stdio.h>
#include <string.h> /* função strstr */
int main (void)
{
int n = 0; /* número da linha corrente */
int achou = 0; /* indica se achou sub-cadeia */
char entrada[121]; /* armazena nome do arquivo de entrada */
char subcadeia[121]; /* armazena sub-cadeia */
char linha[121]; /* armazena cada linha do arquivo */
FILE* fp; /* ponteiro do arquivo de entrada */
/* pede ao usuário o nome do arquivo e a sub-cadeia */
printf("Digite o nome do arquivo de entrada: ");
scanf("%120s",entrada);
printf("Digite a sub-cadeia: ");
scanf("%120s",subcadeia);
/* abre arquivo para leitura */
fp = fopen(entrada,"rt");
if (fp == NULL) 
{ printf("Não foi possível abrir arquivo de entrada.\n"); 
return 1; }
2/6/2005 (c) Dept. Informática - PUC-Rio 29
/* lê linha a linha */
while (fgets(linha,121,fp) != NULL) 
{
n++;
if (strstr(linha,subcadeia) != NULL) 
{ achou = 1; break; }
}
/* fecha arquivo */
fclose(fp);
/* exibe saída */
if (achou)
printf("Achou na linha %d.\n", n);
else
printf("Nao achou.");
return 0;
}
2/6/2005 (c) Dept. Informática - PUC-Rio 30
Estruturação de dados em arquivos textos
• Exemplo de acesso linha a linha:
– arquivo com uma lista de retângulos, 
triângulos e círculos
– formato das linhas do arquivo: 
• linha com dados de figura:
– caractere indicando o tipo de figura (r, t ou c)
– parâmetros que definem a figura: 
retângulos e triângulos: base e altura
círculos: raio
• linha iniciada com o caractere #
– representa comentário e deve ser desconsiderada
• linha em branco 
– permitida, mas deve ser desprezada
# Lista de figuras
r 2.0 1.2
c 5.8
# t 1.23 12
t 4 1.02
c 5.1
2/6/2005 (c) Dept. Informática - PUC-Rio 31
Estruturação de dados em arquivos textos
int sscanf (char* s, char* formato, ...);
• parâmetros:
– cadeia de caracteres representando a string
– formato e lista de endereços de variáveis que fornecerão os 
dados a serem capturados da string (como na função scanf)
• valor de retorno:
– número de dados lidos com sucesso
• definição:
– similar às funções scanf e fscanf
– captura os valores armazenados numa string
2/6/2005 (c) Dept. Informática - PUC-Rio 32
Estruturação de dados em arquivos textos
• Programa para interpretar o arquivo:
– para cada linha lida do arquivo, 
• leia um caractere do conteúdo da linha 
(desprezando eventuais caracteres brancos iniciais) 
seguido de dois números reais
– se nenhum dado for lido com sucesso, 
• há uma linha vazia, que deve ser desprezada
– se pelo menos um caractere for lido com sucesso, 
• é possível interpretar o tipo da figura geométrica armazenada na linha ou 
detectar a ocorrência de um comentário
– se for um retângulo ou um triângulo, 
• os dois valores reais também deverão ter sido lidos com sucesso
– se for um círculo, 
• apenas um valor real deverá ter sido lido com sucesso
2/6/2005 (c) Dept. Informática - PUC-Rio 33
char c;
float v1, v2;
FILE* fp;
char linha[121];
...
while (fgets(linha,121,fp)) 
{ int n = sscanf(linha," %c %f %f",&c,&v1,&v2);
if (n>0) 
{ switch(c) 
{ case ’#’: /* desprezar linha de comentário */
break;
case 'r': if (n!=3) { /* tratar erro de formato do arquivo */ ... }
else { /* tratar retângulo: base = v1, altura = v2 */ ... }
break;
case 't': if (n!=3) { /* tratar erro de formato do arquivo */ ... }
else { /* tratar triângulo: base = v1, altura = v2 */ ... }
break;
case 'c': if (n!=2) { /* tratar erro de formato do arquivo */ ... }
else { /* tratar círculo: raio = v1 */ ... }
break;
default: /* tratar erro de formato do arquivo */ ...
break;
}
}
}
...
2/6/2005 (c) Dept. Informática - PUC-Rio 34
Estruturação de dados em arquivos textos
• Acesso via palavras-chaves:
– adotado quando os objetos num arquivo têm descrições de 
tamanhos variados
– cada objeto é precedido por uma palavra-chave que o identifica
– interpretação do arquivo pode ser feita lendo-se as palavras-
chaves e interpretando a descrição do objeto correspondente 
2/6/2005 (c) Dept. Informática - PUC-Rio 35
Estruturação de dados em arquivos textos
• Exemplo de acesso via palavras-chaves:
– arquivo contendo uma lista de 
retângulos, triângulos, círculos 
e polígonos quaisquer 
– cada polígono é descrito pelo 
número de vértices que o compõe, 
seguido das coordenadas dos vértices 
RETANGULO
b h
TRIANGULO
b h
CIRCULO
r
POLIGONO
n
x1 y1
x2 y2
…
xn yn
2/6/2005 (c) Dept. Informática - PUC-Rio 36
...
FILE* fp;
char palavra[121];
...
while (fscanf(fp,"%120s",palavra) == 1)
{
if (strcmp(palavra,"RETANGULO")==0) {
/* interpreta retângulo */
}
else if (strcmp(palavra,"TRIANGULO")==0) {
/* interpreta triângulo */
}
else if (strcmp(palavra,"CIRCULO")==0) {
/* interpreta círculo */
}
else if (strcmp(palavra,"POLIGONO")==0) {
/* interpreta polígono */
}
else {
/* trata erro de formato */
}
}
strcmp(s,t)==0 , se c=t
<0 , se c<t
>0 , se c>t
(a ordem é lexicográfica)
2/6/2005 (c) Dept. Informática - PUC-Rio 37
Arquivos em modo binário
• Arquivo em modo binário:
– utilizado para salvar (e depois recuperar) 
oconteúdo da memória principal diretamente no disco
• cada byte da memória é copiado para o arquivo
• Funções:
int fwrite (void* p, int tam, int nelem, FILE* fp);
int fread (void* p, int tam, int nelem, FILE* fp);
int fseek (FILE* fp, long offset, int origem);
2/6/2005 (c) Dept. Informática - PUC-Rio 38
Arquivos em modo binário
int fwrite (void* p, int tam, int nelem, FILE* fp);
• parâmetros:
p representa o endereço de memória a partir do qual
bytes devem ser copiados para o arquivo
tam indica o tamanho, em bytes, de cada elemento
nelem indica o número de elementos
fp ponteiro do arquivo binário para o qual 
o conteúdo da memória será copiado
• definição:
– escreve (salva) dados em arquivos binários 
2/6/2005 (c) Dept. Informática - PUC-Rio 39
Arquivos em modo binário
int fread (void* p, int tam, int nelem, FILE* fp);
• parâmetros:
p representa o endereço de memória a partir do qual
os bytes lidos para o arquivo serão colocados
tam indica o tamanho, em bytes, de cada elemento
nelem indica o número de elementos
fp ponteiro do arquivo binário do qual dados serão lidos
• definição:
– lê (recupera) dados de arquivos binários
2/6/2005 (c) Dept. Informática - PUC-Rio 40
Arquivos em modo binário
• Exemplo:
– aplicação com conjunto de pontos armazenados num vetor
– tipo definindo o ponto: 
struct ponto {
float x, y, z;
};
typedef struct ponto Ponto;
2/6/2005 (c) Dept. Informática - PUC-Rio 41
Arquivos em modo binário
• Exemplo (cont.):
– função para salvar o conteúdo de um vetor de pontos:
• recebe como parâmetros o nome do arquivo, o número de pontos 
no vetor e o ponteiro para o vetor 
void salva (char* arquivo, int n, Ponto* vet)
{
FILE* fp = fopen(arquivo,"wb");
if (fp==NULL) {
printf("Erro na abertura do arquivo.\n");
exit(1);
}
fwrite(vet, sizeof(Ponto), n, fp);
fclose(fp);
}
2/6/2005 (c) Dept. Informática - PUC-Rio 42
Arquivos em modo binário
• Exemplo (cont.):
– função para recuperar os dados salvos
void carrega (char* arquivo, int n, Ponto* vet)
{
FILE* fp = fopen(arquivo,"rb");
if (fp==NULL) {
printf("Erro na abertura do arquivo.\n");
exit(1);
}
fread(vet, sizeof(Ponto), n, fp);
fclose(fp);
}
2/6/2005 (c) Dept. Informática - PUC-Rio 43
Arquivos em modo binário
int fseek (FILE* fp, long offset, int origem);
• parâmetros:
fp arquivo cujo cursor será re-posicionando
offset de quantos bytes o cursor deve avançar
origem em relação a que posição o cursor deve ser avançado
SEEK_CUR em relação à posição corrente
SEEK_SET em relação ao início do arquivo
SEEK_END em relação ao final do arquivo
• definição:
– altera a posição do cursor do arquivo
2/6/2005 (c) Dept. Informática - PUC-Rio 44
Arquivos em modo binário
• Exemplo (cont.):
– função para capturar o i-ésimo ponto armazenado em um 
arquivo de pontos no espaço 3D salvo como definido 
anteriormente
Ponto le_ponto (FILE* fp, int i)
{
Ponto p;
fseek(fp, i*sizeof(Ponto), SEEK_SET);
fread(&p, sizeof(Ponto), 1, fp);
return p;
}
2/6/2005 (c) Dept. Informática - PUC-Rio 45
Resumo
• Funções para abrir e fechar arquivos:
FILE* fopen (char* nome_arquivo, char* modo);
int fclose (FILE* fp);
• Funções para arquivo em modo texto:
int fscanf (FILE* fp, char* formato, ...);
int fgetc (FILE* fp);
char* fgets (char* s, int n, FILE* fp);
int fprintf(FILE* fp, char* formato, ...);
int fputc (int c, FILE* fp);
• Funções para arquivos em modo binário:
int fwrite (void* p, int tam, int nelem, FILE* fp);
int fread (void* p, int tam, int nelem, FILE* fp);
int fseek (FILE* fp, long offset, int origem);

Continue navegando