Buscar

pc1-cap6

Prévia do material em texto

© ELFS 184 
Arquivos de Dados 
•  Imagine a seguinte situação: 
•  Um programa precisa ler duas matrizes 10 x 10. 
•  O usuário terá que digitar 200 valores. 
•  O programa vai precisar ser executado novamente. 
•  O usuário terá que digitar os 200 valores novamente. 
•  Como evitar isso? Armazenando os valores em um arquivo
 e, sempre que o programa for executado, efetuar a leitura
 dos valores a partir do arquivo. 
•  Arquivos são usados para armazenar dados de forma
 permanente (lembrar que o armazenamento de dados na
 memória do computador é temporário, isto é, os dados se
 perdem quando o programa termina sua execução). 
© ELFS 185 
•  Aplicações empresariais como, por exemplo, cadastro de
 clientes, controle de estoque, gestão financeira,
 processam muitos dados e não seriam possíveis sem o uso
 de arquivos. 
•  Arquivos são armazenados em dispositivos de memória
 externos e podem reter grandes volumes de dados por
 longos períodos de tempo. 
•  Como são externos, os arquivos não fazem parte de
 programas. Os programas apenas utilizam os arquivos. 
•  A linguagem C não impõe estrutura alguma aos arquivos.
 Para um programa C, um arquivo é simplesmente uma
 sequência de bytes. 
•  Para utilizar um arquivo de dados, é preciso declarar um
 ponteiro para o tipo FILE. 
FILE *arq; 
© ELFS 186 
•  A variável arq representa no programa o nome interno de
 um arquivo (externo) de dados. 
•  Para que o arquivo possa ser utilizado no programa é
 preciso informar onde o arquivo se encontra (uma vez que
 o arquivo é externo ao programa). 
•  Esta operação é conhecida como abertura do arquivo e é
 executada pela função fopen. 
•  A função fopen tem 2 parâmetros do tipo string. O
 primeiro parâmetro especifica o nome do arquivo (que
 deve incluir a pasta onde o arquivo se encontra). 
FILE *arq; 
arq = fopen("dados.txt","r"); 
arq = fopen("c:\\arquivos\\dados.txt","r"); 
© ELFS 187 
•  Se a pasta não for informada, considera-se que o arquivo
 esteja presente na mesma pasta que contém o programa. 
•  Se, por alguma razão, o arquivo não puder ser aberto, a
 função fopen irá retornar o valor NULL. 
•  O segundo parâmetro da função fopen especifica o que se
 pretende fazer. As possibilidades são: 
•  "r": Ler os dados existentes ("read"); 
•  "w": Escrever dados, apagando os existentes ("write"); 
•  "a": Anexar novos dados aos já existentes ("append"). 
FILE *arq; 
arq = fopen("dados.txt","r"); 
if (arq == NULL) 
{ 
 printf("Erro ao abrir o arquivo"); 
 return 0; 
} 
© ELFS 188 
•  Resumindo: 
Modo Significado 
“r” 
Abre um arquivo existente para leitura de 
dados; se o arquivo não existir, irá ocorrer um 
erro. 
“w” 
Abre um novo arquivo para gravação de 
dados; se o arquivo já existir, a gravação irá 
sobrescrever os dados existentes. 
“a” 
Abre um arquivo para anexação de dados; se 
o arquivo não existir, será criado um novo 
arquivo. 
© ELFS 189 
•  Imagine que o arquivo dados.txt contém os seguintes
 dados: 
•  Para ler o dados do arquivo, deve-se usar a função fscanf. 
 Exemplo: 
Para criar um 
arquivo no ambiente 
CETUS, use sempre 
a extensão .txt para 
o nome do arquivo. 
3 5 
1 3 2 6 8 
3 2 0 9 1 
7 2 4 3 7 
2 7 3 8 8 
3 0 1 9 1 
5 5 2 0 6 
Dimensões das matrizes 
Linhas das matrizes 
ma 
mb 
fscanf(arq,"%d %d",&nl,&nc); 
for (i = 0; i < nl; i++) 
 for (j = 0; j < nc; j++) 
 fscanf(arq,"%d",&ma[i][j]); 
© ELFS 190 
•  Observe que a leitura depende da disposição dos dados no
 arquivo. Por exemplo, se os dados estivessem dispostos
 como: 
 a leitura seria: 
fscanf(arq,"%d %d",&nl,&nc); 
for (i = 0; i < nl; i++) 
{ 
 for (j = 0; j < nc; j++) 
 fscanf(arq,"%d",&ma[i][j]); 
 for (j = 0; j < nc; j++) 
 fscanf(arq,"%d",&mb[i][j]); 
} 
3 5 
1 3 2 6 8 2 7 3 8 8 
3 2 0 9 1 3 0 1 9 1 
7 2 4 3 7 5 5 2 0 6 
ma mb 
© ELFS 191 
•  Depois que os dados foram lidos, deve-se fechar o arquivo
 usando a função fclose: 
•  Se o fechamento do arquivo for bem sucedido, a função
 fclose retorna o valor 0. Caso contrário, retorna o valor -1. 
•  Todos os arquivos abertos que não forem fechados pela
 função fclose, serão fechados quando o programa
 terminar sua execução. 
•  Para escrever dados em um arquivo, deve-se usar a função
 fprintf. Para isso, o arquivo deve ser aberto no modo "w"
 ou "a". 
 Exemplo: gerar uma matriz N x N com valores aleatórios e
 gravar no arquivo matriz.txt. 
fclose(arq); 
© ELFS 192 
int i,j,N,M[50][50]; 
FILE *f; 
N = aleatorio(1,50); 
for (i = 0; i < N; i++) 
 for (j = 0; j < N; j++) 
 M[i][j] = aleatorio(10,99); 
f = fopen("matriz.txt","w"); 
if (f == NULL) 
{ 
 printf("Erro ao abrir o arquivo"); 
 return 0; 
} 
fprintf(f,"%d\n",N); 
for (i = 0; i < N; i++) 
{ 
 for (j = 0; j < N; j++) 
 fprintf(f,"%3d",M[i][j]); 
 fprintf(f,"\n"); 
} 
fclose(f); 
© ELFS 193 
•  Exercício. Gerar, aleatoriamente, uma matriz D de
 distâncias entre N cidades e gravar a matriz gerada no
 arquivo dist.txt. A matriz D deve ser simétrica (D[i][j]
 deve ser igual a D[j][i]). Além disso, D[i][i] = 0. O valor
 de N deve ser fornecido pelo usuário (MAX = 50). 
•  Como garantir que a matriz gerada seja simétrica? 
•  Linha 0: gerar os elementos das colunas 1, 2, ..., N-1 
•  Linha 1: gerar os elementos das colunas 2, ..., N-1 
... 
•  Linha i: gerar quais elementos? 
0 8 5 2 
0 4 7 
0 3 
0 
Uma ideia é gerar aleatoriamente 
apenas os elementos que estão acima 
da diagonal principal. 
© ELFS 194 
#define MAX 50 
int main() 
{ 
 int i,j,N,D[MAX][MAX]; 
 FILE *sai; 
 printf("Quantas cidades? "); 
 scanf("%d",&N); 
 // Diagonal principal 
 for (i = 0; i < N; i++) 
 { 
 D[i][i] = 0; 
 } 
 // Acima da diagonal 
 for (i = 0; i < N; i++) 
 { 
 for (j = i+1; j < N; j++) 
 { 
 D[i][j] = aleatorio(10,99); 
 D[j][i] = D[i][j]; 
 } 
 } 
© ELFS 195 
 // Abrir arquivo para escrita 
 sai = fopen("dist.txt","w"); 
 if (sai == NULL) 
 { 
 printf("Erro ao abrir arquivo dist.txt"); 
 return 0; 
 } 
 // Escrever os dados no arquivo 
 for (i = 0; i < N; i++) 
 { 
 for (j = 0; j < N; j++) 
 { 
 fprintf(sai,"%3d",D[i][j]); 
 } 
 fprintf(sai,"\n"); 
 } 
 // Fechar o arquivo 
 fclose(sai); 
 return 0; 
} 
© ELFS 196 
•  As funções scanf e printf são usadas apenas para os
 dispositivos padrões de entrada (stdin) e de saída
 (stdout). 
•  Alguns dispositivos padrões: 
•  As funções fscanf e fprintf são generalizações das funções
 scanf e printf, podendo ser usadas para qualquer tipo de
 arquivo. 
Nome Dispositivo Significado 
stdin Teclado Dispositivo padrão de entrada 
stdout Vídeo Dispositivo padrão de saída 
stdprn Porta paralela Dispositivo padrão de impressão 
scanf (...) 
é equivalente a 
fscanf(stdin, ...) 
printf(...) fprintf(stdout, ...) 
© ELFS 197 
•  Exercício. Considere que o arquivo pessoas.txt armazena a
 idade (int) e o peso (float) de N pessoas. O valor de N
 encontra-se na primeira linha do arquivo. Fazer um
 programa para mostrar qual é a pessoa mais jovem e qual
 é a pessoa mais pesada. 
int main() 
{ 
 FILE *arq; 
 int np,N,idade,mIdade,jovem,gordo; 
 float peso,mPeso; 
 arq = fopen("pessoas.txt","r"); 
 if (arq == NULL) 
 { 
 printf("Erro ao abrir arquivo pessoas.txt\n"); 
 return 0; 
 } 
 fscanf(arq,"%d",&N); 
50 
28 35.6 
13 18.5 
21 40.9 
44 51.7 
... 
© ELFS 198 
 mIdade = 1000; 
 mPeso = 0; 
 for (np = 1; np <= N; np++) 
 { 
 fscanf(arq,"%d %f",&idade,&peso); 
 if (idade < mIdade) 
 { 
 mIdade = idade; 
 jovem = np; 
 } 
 if (peso > mPeso) 
 { 
 mPeso = peso; 
 gordo = np; 
 } 
 } 
 fclose(arq); 
 printf("%d e' a mais jovem (idade = %d)\n",jovem,mIdade); 
 printf("%d e' a mais pesada (peso = %.2f)\n",gordo,mPeso); 
 return 0; 
} 
© ELFS 199 
•  E se o arquivo não contém, na primeira linha,
 o número de pessoas? 
•  Quantas linhas devem ser lidas? 
28 35.6 
13 18.5 
21 40.9 
44 51.7 
... 
•  Devem ser lidas tantas linhas até se chegarao final do
 arquivo. O final do arquivo é detectado pela função feof()
 (eof significa end-of-file). 
•  Como a função feof() detecta o final de um arquivo?
 Quando houver uma tentativa de leitura de uma nova
 linha do arquivo (que não existe!). 
•  Portanto, feof(arq) retorna: 
•  true, se após uma tentativa de leitura, constata-se que
 o arquivo arq não contém mais linhas a serem lidas; 
•  false, se uma tentativa de leitura foi bem sucedida. 
Importante: Ao final de cada linha do arquivo deve haver uma 
mudança de linha ("\n"), inclusive na última linha que contém dados. 
© ELFS 200 
•  Então, quando se sabe o número de linhas do arquivo: 
•  Quando não se sabe o número de linhas do arquivo: 
•  Observar que a execução da função feof() deve ser
 precedida pela execução da função fscanf(). 
for (np = 1; np <= N; np++) 
{ 
 fscanf(arq,"%d %f",&idade,&peso); 
 ... 
} 
np = 0; 
fscanf(arq,"%d %f",&idade,&peso); 
while (!feof(arq)) 
{ 
 np++; 
 ...(processar a linha lida) 
 fscanf(arq,"%d %f",&idade,&peso); 
} 
© ELFS 201 
•  Exercício. Um banco armazena em cada linha do arquivo
 clientes.txt as seguintes informações: código do cliente
 (int) e o saldo (float) de sua conta no início do mês. O
 banco armazena em cada linha do arquivo
 lancamentos.txt as seguintes informações: código do
 cliente (int), código do lançamento (1 = entrada; -1 =
 saída), valor do lançamento (float). Escrever um programa
 que, dado um código de cliente, mostra o total de
 entradas, o total de saídas e o saldo atual da conta deste
 cliente. 
101 2580.25 
118 1540.50 
123 -500.00 
125 1500.00 
... 
clientes.txt 
101 1 25.25 
101  1 30.00 
123 -1 15.50 
123 -1 100.00 
101 -1 15.80 
118  1 500.00 
101 -1 32.00 
... 
lancamentos.txt Qual é o saldo do 
cliente 101? 
2580.25 + 25.25 + 
30.00 – 15.80 – 32.00 
= 2587.70 
© ELFS 202 
#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
 FILE *cli,*lan; 
 int nc,cliente,tipo,achei; 
 float saldo,valor,totEnt,totSai; 
 cli = fopen("clientes.txt","r"); 
 if (cli == NULL) 
 { 
 printf("Erro ao abrir arquivo clientes.txt\n"); 
 return 0; 
 } 
 lan = fopen("lancamentos.txt","r"); 
 if (lan == NULL) 
 { 
 printf("Erro ao abrir arquivo lancamentos.txt\n"); 
 return 0; 
 } 
 printf("Qual cliente? "); 
 scanf("%d",&nc); 
© ELFS 203 
 // Recuperar o saldo inicial do cliente 
 achei = 0; 
 fscanf(cli,"%d %f",&cliente,&saldo); 
 while (!feof(cli)) 
 { 
 if (cliente == nc) 
 { 
 achei = 1; 
 break; 
 } 
 fscanf(cli,"%d %f",&cliente,&saldo); 
 } 
 fclose(cli); 
 if (achei == 0) 
 { 
 printf("Cliente %d nao existe!\n",nc); 
 return 0; 
 } 
© ELFS 204 
 // Recuperar os lancamentos do cliente 
 totEnt = 0; 
 totSai = 0; 
 fscanf(lan,"%d %d %f",&cliente,&tipo,&valor); 
 while (!feof(lan)) 
 { 
 if (cliente == nc) 
 { 
 if (tipo == 1) 
 totEnt = totEnt + valor; 
 else 
 totSai = totSai + valor; 
 } 
 fscanf(lan,"%d %d %f",&cliente,&tipo,&valor); 
 } 
 fclose(lan); 
 printf("Cliente %d\n",nc); 
 printf("Saldo inicial = %.2f\n",saldo); 
 printf("Total de entradas = %.2f\n",totEnt); 
 printf("Total de saidas = %.2f\n",totSai); 
 saldo = saldo + totEnt - totSai; 
 printf("Saldo atual = %.2f\n",saldo); 
 return 0; 
} 
© ELFS 205 
•  Exercício. Escrever um programa que, dado o valor de N,
 gera uma matriz M (N x N) com valores aleatórios no
 intervalo [0, 9], chama a função void contagem(int N, int
 M[][10], int C[]), que determina o vetor C, e escreve no
 arquivo conta.txt quantas vezes cada elemento de M
 aparece na matriz. Observar que o valor de C[k] deve ser
 igual ao número de vezes em que k aparece na matriz M. 
Exemplo: 
2 4 6 3 9 
6 9 3 9 9 
1 7 0 4 6 
6 3 3 1 2 
9 7 6 9 7 
0 aparece 1 vezes 
1 aparece 2 vezes 
2 aparece 2 vezes 
3 aparece 4 vezes 
4 aparece 2 vezes 
5 aparece 0 vezes 
6 aparece 5 vezes 
7 aparece 3 vezes 
8 aparece 0 vezes 
9 aparece 6 vezes 
Matriz gerada: 
Arquivo conta.txt: 
© ELFS 206 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
int aleatorio(int a, int b) 
{ 
 return (a + rand()%(b-a+1)); 
} 
void contagem(int N, int M[][10], int C[]) 
{ 
 int i,j,x; 
 for (i = 0; i < 10; i++) 
 C[i] = 0; 
 for (i = 0; i < N; i++) 
 { 
 for (j = 0; j < N; j++) 
 { 
 x = M[i][j]; 
 C[x]++; 
 } 
 } 
 return; 
} 
© ELFS 207 
int main() 
{ 
 int i,j,N,M[10][10],C[10]; 
 FILE *arq; 
 srand((unsigned)time(NULL)); 
 printf("Tamanho: "); 
 scanf("%d",&N); 
 if (N > 10) 
 { 
 printf("Erro: Tamanho maximo = 10\n"); 
 return 0; 
 } 
 printf("Matriz gerada:\n"); 
 for (i = 0; i < N; i++) 
 { 
 for (j = 0; j < N; j++) 
 { 
 M[i][j] = aleatorio(0,9); 
 printf("%d ",M[i][j]); 
 } 
 printf("\n"); 
 } 
© ELFS 208 
 contagem(N,M,C); 
 arq = fopen("conta.txt","w"); 
 for (i = 0; i < 10; i++) 
 { 
 fprintf(arq,"%d aparece %d vezes\n",i,C[i]); 
 } 
 fclose(arq); 
 printf("Arquivo conta.txt gerado!\n"); 
 return 0; 
} 
•  Exercício. Modificar o programa de modo que, no arquivo
 conta.txt sejam mostrados apenas os elementos que
 aparecem 1 ou mais vezes na matriz M. 
•  Exercício: Modificar o programa para incluir também no
 arquivo conta.txt a mensagem de qual foi o elemento
 que apareceu mais vezes na matriz M. 
© ELFS 209 
•  Exercício. Uma empresa armazena no arquivo dados.txt as 
seguintes informações sobre os funcionários da empresa: 
matrícula, salário-base (sb), número de faltas (nf), número 
de horas-extras (he). 
O salário a ser pago para cada funcionário é definido por: 
salário = sb × ( (30 – nf) / 30 + 1,5 × he / 240 ) 
Fazer um programa que lê as informações do arquivo 
dados.txt e escreve no arquivo folha.txt a matrícula e o 
valor do salário para cada um dos funcionários da empresa. 
O programa deve mostrar o valor total da folha de 
pagamentos da empresa e também escrever no arquivo 
folha.txt esse valor total. 
© ELFS 210 
#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
 int i,mat,nf,he; 
 float sb,sal,total; 
 FILE *arq,*sai; 
 arq = fopen("dados.txt","r"); 
 if (arq == NULL) 
 { 
 printf("Erro ao abrir dados.txt\n"); 
 return 0; 
 } 
 sai = fopen("folha.txt","w"); 
 if (sai == NULL) 
 { 
 printf("Erro ao abrir folha.txt\n"); 
 return 0; 
 } 
© ELFS 211 
 total = 0; 
 fscanf(arq,"%d %f %d %d",&mat,&sb,&nf,&he); 
 while (!feof(arq)) 
 { 
 sal = sb*((30.0-nf)/30 + 1.5*he/240); 
 fprintf(sai,"%d %.2f\n",mat,sal); 
 total = total + sal; 
 fscanf(arq,"%d %f %d %d",&mat,&sb,&nf,&he); 
 } 
 printf("Total da folha de pagamento = %.2f\n",total); 
 fprintf(sai,"%.2f\n",total); 
 fclose(arq); 
 fclose(sai); 
 return 0; 
}

Continue navegando

Outros materiais