Você está na página 1de 49

Para esta aula foram utilizados slides do Prof. Bruno Kimura (UNIFEI) e do Prof.

Casanova (PUC-RIO)

Arquivos
Memória Principal

Armazenamento primário (RAM e cache)


● É manipulado diretamente pela UCP.
● São elementos voláteis com alta taxa de transferência
(acesso é rápido)
● Possuem capacidade limitada.
Memória Secundária

Armazenamento secundário (CD, HD, fitas)


● Dispositivos não voláteis com maior capacidade de
armazenamento.
● Armazenamento geralmente é feito por meio magnético.
● Acesso é lento.
● Menor custo de armazenagem.
Entrada e Saída de Dados:
Prompt de Comando
Entrada e Saída

● Por prompt de comando (console) (já sabemos como implementar)


● Por arquivos
● Pela rede
As operações de Entrada e Saída (E/S) em ANSI C são efetuadas por funções
implementadas em bibliotecas da linguagem .

Leitura formatada: stdio.h

int scanf(const char *format, ...)

Obtém dados da entrada padrão STDIN (teclado).

Escrita formatada: stdio.h


Streams
Entrada e Saída de Dados:
Arquivos
Fluxos de Dados (Streams)

● A linguagem C utiliza a abstração de fluxo (stream) de dados para E/S:


○ Permite isolar a aplicação dos detalhes de hardware do dispositivos de
armazenamento
○ Todos os diferentes sistemas de arquivos se comportam da mesma
maneira quando manipulados como um fluxo contínuo de dados.

E/S pode ser manipulada em dois diferentes tipos de fluxos:

● fluxos de texto
● fluxos binários
Entrada e Saída de Dados:
Arquivos
Fluxos de Texto (Stream de Texto)

● Composto por sequências de caracteres (human readable), que pode ou


não ser dividida em linhas, terminadas por um caractere de final de linha.
Um texto.
○ *.txt
Entrada e Saída de Dados:
Arquivos
Fluxos de Texto (Stream de Texto)

● Composto por sequências de caracteres (human readable), que pode ou


não ser dividida em linhas, terminadas por um caractere de final de linha.
Um texto.
○ *.txt

Fluxo Binário (Stream Binário)

● Composto por uma seqüência de bytes lidos ou escritos diretamente em um


arquivo binário no dispositivo.
○ *.exe
○ *.o
○ *.pdf
○ *.doc
○ *.gif
○ *.jpg
Entrada e Saída de Dados:
Arquivos
Fluxos de Texto (Stream de Texto)

● Composto por sequências de caracteres (human readable), que pode ou


não ser dividida em linhas, terminadas por um caractere de final de linha.
Um texto.
○ *.txt

Fluxo Binário (Stream Binário)

● Composto por uma seqüência de bytes lidos ou escritos diretamente em um


arquivo binário no dispositivo.
○ *.exe
○ *.o
○ *.pdf
○ *.doc
○ *.gif
○ *.jpg
Serviços do 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
Principais funções

fopen() : cria ou abre um arquivo


fclose() : fecha um arquivo
fputc() : escreve um caracter num arquivo
fgetc() : Lê um caracter do arquivo
fprintf(): o mesmo que printf para arquivo
fscanf() : o mesmo que scanf para arquivo
feof() : indica final de arquivo
fread() : lê blocos de bytes do arquivo
fwrite() : escreve blocos de bytes no arquivo
rewind() : volta p/ o inicio do arquivo
remove() : Apaga um arquivo
fseek() : Altera o indicador de leitura/escrita do arquivo para uma nova posição
ftell() : obtém a posição corrente do offset
Funções para abrir e fechar arquivos

FILE* fopen (char* nome_arquivo, char* modo);


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
○ devemos checar o retorno do fopen, antes de usar o
buffer.
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
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
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
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);
}
printf("irei ler este arquivo de texto\n");
...
Funções para abrir e fechar arquivos

Passando argumentos para o programa

● Os parametros argc e argv, contem o numero de argumentos e um vetor de


"string" com os argumentos passados.
● O primeiro argumento é o nome do programa.
int main (int argc, char** argv) {
int i;
for (i =0 ; i < argc; i++)
printf ("argumento %d eh %s\n", i, argv[i]);
}

> gcc arq.c -o programa


> programa arg2 arg3
argumento 0 eh progra
argumento 1 eh arg2
argumento 2 eh arg3
Funções para abrir e fechar arquivos

Usando os argumentos do programa para abrir um arquivo


int main (int argc, char** argv) {
FILE* fp;
if (argc < 2) {
printf("Entre com o nome do arquivo a ser aberto\n");
exit(1);
}

fp = fopen(argv[1],"rt");
if (fp == NULL) {
printf("Erro na abertura do arquivo!\n");
exit(1);
}
printf("irei ler o arquivo %s \n", argv[1]);
}
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
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
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);
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
Exemplo

Dado o seguinte arquivo:


12 14 15 67

Posso ler:

while ( !feof(fp) ) {
fscanf (fp,"%d",&num);
printf ("%d\n", num);
}
Exemplo 2

Dado o seguinte arquivo:


12 14 15 67

Posso ler, como se fosse pares de coordenadas:

while ( !feof(fp) ) {
fscanf (fp,"%d %d",&x, &y);
printf ("(%d,%d)\n",x, y);
}
Exemplo 3

Dado o seguinte arquivo:


12 14 15 67

Ao invés de testar se chegou no final do arquivo, posso


testar o retorno do scanf.

while ( fscanf (fp,"%d %d",&x, &y) ==2 )


printf ("(%d,%d)\n",x, y);
Exemplo 4 - Incluindo Caractere de
formatação
Dado o seguinte arquivo:
12 - 14
15 - 67
Ao invés de testar se chegou no final do arquivo, posso
testar o retorno do scanf.

while ( fscanf (fp,"%d - %d",&x, &y) ==2 )


printf ("(%d,%d)\n",x, y);
Atividade

Considere um arquivo com o nome dos alunos e suas


notas:
Joao 50 30 40
Maria 10 100 80
Jose 40 50 60

Escrevam um programa completo, que leia este arquivo e


imprima se o aluno foi ou não aprovado e qual a sua média
final. O aluno precisa de uma média maior que 60.
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)


Arquivos em modo texto

Exemplo

...
fprintf (fp,"(%d,%d)\n",10, 20);
fprintf (fp,"(%d,%d)\n",45, 60);
...

Produz

(10,20)
(45,60)
Atividade

Usando a atividade anterior, agora ao invés de imprimir na


tela. Salve em um arquivo o nome do aluno, sua média e se
foi aprovado. Exemplo:

Joao 40 Reprovado

O arquivo de saída será informado via argumentos do


programa:

nota_final notas.txt final.txt


Lendo caracter a caracter

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
Escrevendo caracter a caracter

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
Atividade
● Façam um programa que copie um arquivo de
entrada para um arquivo de saída (texto).
Exemplo de uso:
copia entrada.txt saida.txt
Lendo linha a linha

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
Atividade: Fazer um programa para ler este
arquivo.
● arquivo com uma lista de retângulos, triângulos e círculos
● formato das linhas do arquivo:
# Lista de figuras
○ linha com dados de figura
■ caractere indicando o tipo de figura (r, t ou c) r 2.0 1.2
c 5.8
■ parâmetros que definem a figura:
■ retângulos e triângulos: base e altura # t 1.23 12
t 4.0 1.02
■ círculos: raio
● linha iniciada com o caractere # c 5.1
○ representa comentário e deve ser desconsiderada
● linha em branco
○ permitida, mas deve ser desprezada
Arquivos em modo binário
● Arquivo em modo binário:
– utilizado para salvar (e depois recuperar)
● o conteú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);
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
Exemplo de escrita e leitura
typedef struct Aluno {
int mat;
char nome[10];
} Aluno;

int main () {
FILE *f, *f2; Aluno a, b;
// gravando
f = fopen ("teste.bin", "wb");
a.mat = 12456; strcpy(a.nome, "joao");
fwrite (&a,sizeof(Aluno), 1, f);
fclose (f);
//lendo
f = fopen ("teste.bin", "rb");
fread (&b, sizeof(Aluno), 1, f);
printf("%d %s\n", b.mat, b.nome);
return 0;
}
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
Exemplo de fseek
int main () {
FILE *f, *f2; Aluno a, b;
// gravando
f = fopen ("teste.bin", "wb+");
a.mat = 12456; strcpy(a.nome, "joao");
fwrite (&a,sizeof(Aluno), 1, f);
Volta ao
fseek (f, 0, SEEK_SET); inicio
fread (&b, sizeof(Aluno), 1, f);
printf("%d %s\n", b.mat, b.nome);
return 0;
}
Exemplo de fseek - rewind
int main () {
FILE *f, *f2; Aluno a, b;
// gravando
f = fopen ("teste.bin", "wb+");
a.mat = 12456; strcpy(a.nome, "joao");
fwrite (&a,sizeof(Aluno), 1, f);
Volta ao
rewind (f); inicio
fread (&b, sizeof(Aluno), 1, f);
printf("%d %s\n", b.mat, b.nome);
return 0;
}
Exemplo de fseek
int main () {
FILE *f, *f2; Aluno a, b;
// gravando
f = fopen ("teste.bin", "wb+");
a.mat = 12456; strcpy(a.nome, "joao");
fwrite (&a,sizeof(Aluno), 1, f);
Volta ao
fseek (f, 0, SEEK_SET); inicio
fread (&b, sizeof(Aluno), 1, f);
printf("%d %s\n", b.mat, b.nome);
return 0;
}
Exemplo de fseek
int main () {
FILE *f, *f2; Aluno a, b;
// gravando
f = fopen ("teste.bin", "wb+");
a.mat = 12456; strcpy(a.nome, "joao");
fwrite (&a,sizeof(Aluno), 1, f);
Volta ao
fseek (f, -sizeof(Aluno), SEEK_END); inicio
fread (&b, sizeof(Aluno), 1, f);
printf("%d %s\n", b.mat, b.nome);
return 0;
}
Exemplo de fseek
int main () {
FILE *f, *f2; Aluno a, b;
// gravando
f = fopen ("teste.bin", "wb+");
a.mat = 12456; strcpy(a.nome, "joao");
fwrite (&a,sizeof(Aluno), 1, f);
Volta ao
fseek (f, -sizeof(Aluno), SEEK_CUR); inicio
fread (&b, sizeof(Aluno), 1, f);
printf("%d %s\n", b.mat, b.nome);
return 0;
}
ftell

long ftell(FILE *stream);


Obtem o valor da posição corrente do indicador.
• Parâmetros:
– Stream: ponteiro FILE para o arquivo aberto.
• Valor de retorno:
– SUCESSO: retorna o valor do offset (indicador) atual
– FALHA: -1 em caso de erro.
Exemplo de ftell - copiando arquivos
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
FILE *f, *f2; int tam;
char* buffer;
// abrindo um arquivo de entrada
f = fopen (argv[1], "rb");
// descobrindo o tamanho
fseek (f, 0, SEEK_END);
tam = ftell(f);
// voltando para o inicio
rewind (f);
// alocando dinamicamente o buffer para receber dos dados de entrada
buffer = (char*)malloc (sizeof (char) * tam);
fread (buffer, sizeof (char), tam, f); // lendo para o buffer
// abrindo e salvando os dados
f2 = fopen (argv[2], "wb");
fwrite (buffer, sizeof (char), tam, f2); // escrevendo do buffer
fclose (f);
fclose (f2);
return 0;
}
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);
Atividades
● Façam um programa que salve e lê um arquivo
com o nome e três notas de cada aluno.
Diferentemente do exercício de arquivo de
texto, agora monte um programa trabalhando
apenas com arquivo binário. Obs: Usem
registros (struct).

Você também pode gostar