Programação 2007/2008 DEEC-IST 1
Sumário
Estruturas de dados
Noção
Declaração
Operações sobre estruturas
Estruturas como argumento de funções
Passagem por valor
Passagem por referência
Noção de estrutura de dados
Motivação:
Considere o problema do desenvolvimento de uma pequena base
de dados.
Suponha que a base de dados é para ser utilizada em farmácias
de modo a facilitar a gestão da quantidade de medicamentos que
estão armazenados.
Como objectivo pretende-se desenvolver um programa (que
implementa a base de dados), devendo disponibilizar mecanismos
que permitam manipular a informação correspondente aos
diversos medicamentos, por exemplo:
Nome do produto;
Nº de Série;
Lote;
Prazo de validade;
Quantidade armazenada.
Programação 2007/2008 DEEC-IST 3
Noção de estrutura de dados
Questões:
Como é que os dados de um produto devem ser armazenados ?
Qual é o tipo que é mais adequado?
Como é que os dados de todos os produtos devem ser organizados?
Variáveis escalares?
Variáveis vectoriais?
Quais são as acções que devem ser realizadas sobre os dados?
Procurar
Apagar
Acrescentar
Mostrar um produto
Como é que as acções devem ser implementadas ?
Utilizar funções com argumentos. Quais devem ser os argumentos?
Programação 2007/2008 DEEC-IST 4
Noção de estrutura de dados
Como é que os dados de um produto devem ser armazenados ?
Nome do produto
- é uma sequência de caracteres
char
nome[DimNome] =
“”
;
Nº de Série
- em princípio é um número inteiro,
(mas pode ser uma string)int
NumSerie =
0
;
Lote
- pode ser um número inteiro
int
Lote =
0
;
Prazo de validade
-
Pode ser um conjunto de três números inteiros,
int
DiaPV=
0
, MesPV=
0
, AnoPV=
0
;
Ou pode-se utilizar um vector de inteiros
int
Data[
3
] ={
0
,
0
,
0
};
/* Vector */
Quantidade
- em princípio será um número inteiro
Programação 2007/2008 DEEC-IST 5
Noção de estrutura de dados
Na análise anterior apresentou-se como é que a informação de
um produto/medicamento “genérico” pode ser guardada.
Mas num armazém existem diversos produtos, devendo ser
possível aceder à informação de todos esses produtos.
Isto sugere a utilização de vectores, um por cada tipo de
informação.
Assim são necessários 5 vectores.
Noção de estrutura de dados
Como é que os dados de todos os produtos devem ser
organizados ?
Em termos de código C, uma possibilidade consiste em:
#include <stdio.h>
#define PRODNumMAX 1000 #define NOMEDimMAX 50 #define DATADimMAX 3
intmain(void) {
charNomeProd[PRODNumMAX][NOMEDimMAX]; intN_SerieProd[PRODNumMAX]; intN_LoteProd[PRODNumMAX]; intPrazoValidade[PRODNumMAX][DATADimMAX]; intQuantidadeProd[PRODNumMAX]; /* Código Adicional */ return0; }
Programação 2007/2008 DEEC-IST 7
Noção de estrutura de dados
Na prática a informação de um produto não se encontra separada mas é
colocada numa ficha. Um ficha por cada produto. Em C o conceito de
ficha, isto é, um agregado de tipos diferentes mas que se referem ao
mesmo objecto, é designado por uma estrutura de dados.
Para declarar uma estrutura procede-se da forma seguinte:
structFichaProduto { charNomeProd[NOMEDimMAX]; intN_SerieProd; intN_LoteProd; intPrazoValidade[DATADimMAX]; intQuantidadeProd; };
Palavra chave
Nome da estrutura
Programação 2007/2008 DEEC-IST 8
Noção de estrutura de dados
A manipulação de variáveis com tipos heterogéneos é realizada
como se indica. O acesso a um campo da estrutura é feito com o
operador ponto.
/* includes e defines */ intmain (void) {
structFichaProduto { charNomeProd[NOMEDimMAX]; intN_SerieProd; intN_LoteProd; intPrazoValidade[DATADimMAX]; intQuantidadeProd; } prod1;
/* declaração da variavel prod1 do tipo struct FichaProduto */ /* Exemplo da inicializacao da variavel prod1 */
strcpy(prod1.NomeProd,“Tira as Dores”);
prod1.N_SerieProd =20; prod1.N_LoteProd =33; prod1.PrazoValidade[DIA] =02; prod1.PrazoValidade[MES] =12; prod1.PrazoValidade[ANO] =2006; prod1.QuantidadeProd =5000; return0; }
Programação 2007/2008 DEEC-IST 9
Noção de estrutura de dados
De modo a melhorar a legibilidade dos programas, a definição de novos tipos
estruturados devem ser colocadas no ficheiro de definições, o qual é incluido
utilizando a directiva de
#include “...”
. Na declaração das variáveis
estruturadas o tipo assume a forma struct
nome_struct.
Ficheiro: farmacia.h #define PRODNumMAX 1000 #define NOMEDimMAX 50 #define DATADimMAX 3 #define DIA 0 #define MES 1 #define ANO 2 structFichaProduto { charNomeProd[NOMEDimMAX]; intN_SerieProd; intN_LoteProd; intPrazoValidade[DATADimMAX]; intQuantidadeProd; }; Ficheiro: farmacia.c #include “farmacia.h”intmain (void) {
structFichaProduto prod1;
structFichaProduto produtos[PRODNumMAX];
strcpy(prod1.NomeProd,“Tira as Dores”); prod1.N_SerieProd =20; prod1.N_LoteProd =33; prod1.PrazoValidade[DIA] =02; prod1.PrazoValidade[MES] =12; prod1.PrazoValidade[ANO] =2006; prod1.QuantidadeProd =5000; return0; }
Noção de estrutura de dados
Em C podem-se definir estruturas dentro de estruturas, .... No exemplo
de motivação, pode-se substituir o vector que serve para armazenar a
data de validade por uma estrutura.
Ficheiro com as Definições #define PRODNumMAX 1000 #define NOMEDimMAX 50
structDataValidade {
intDia, Mes, Ano; };
structFichaProduto {
charNomeProd[NOMEDimMAX];
intN_SerieProd;
intN_LoteProd;
structDataValidade DataVal;
intQuantidadeProd; };
/* includes e defines */
intmain (void) {
structFichaProduto prod1;
structFichaProduto produtos[PRODNumMAX];
/* Inicializa os campos de prod1 */
strcpy(prod1.NomeProd,“Tira as Dores”); prod1.N_SerieProd =20; prod1.N_LoteProd =33; prod1.DataVal.Dia =02; prod1.DataVal.Mes =12; prod1.DataVal.Ano =2006; prod1.QuantidadeProd =5000; return0; }
Programação 2007/2008 DEEC-IST 11
Manipulação de estruturas de
dados
Operações permitidas com estruturas:
Acesso aos elementos
Atribuição
Permite copiar os conteúdos dos diversos campos
Inicialização na declaração
Permite inicializar o conteúdo dos diversos campos
Estruturas como argumento de funções
Passagem por valor
Passagem por referência
Cálculo da dimensão de uma estrutura
Cálculo do endereço de uma variável estruturada
Programação 2007/2008 DEEC-IST 12
Acesso aos elementos de uma
estruturas de dados
Continuando com o problema da base de dados, é agora
necessário desenvolver uma função que permita
apresentar, no ecrã, a informação de um medicamento.
Acções:
Definir a função, nome e lista de argumentos
Na lista de argumentos deve ser utilizada a técnica da
passagem por valor de uma variável (estruturada), uma vez que
dentro da função não se pretende alterar os campos da variável
com que a função é chamada.
No corpo da função é necessário aceder a cada um dos campos
Programação 2007/2008 DEEC-IST 13
Passagem por valor de estruturas
de dados
Resolução: Código C
voidMostraFicha(structFichaProduto fich,intnumfich) { printf(“--- Ficha N.%d ---\n", numfich); printf("Nome = %s\n", fich.NomeProd);
printf("N_Serie = %d\n", fich.N_SerieProd); printf("N_LoteProd = %d\n", fich.N_LoteProd); printf("Data de Validade = %d/%d/%d\n",
fich.DataVal.Dia, fich.DataVal.Mes, fich.DataVal.Ano); printf("Quantidade = %d\n", fich.QuantidadeProd); }
Nota: Na função MostraFicha, o mecanismo de passagem da variável fich é por
valor. Alterações que sejam feitas na variável fich, não são sentidas na
variável com que a função é chamada para execução.
Tipo da variável
Parâmetro formal
Acesso aos elementos de uma
estruturas de dados
Em seguida é necessário desenvolver uma função que efectue
a leitura dos dados a partir do teclado, devendo armazená-los
na variável com que a função foi chamada, que é exterior à
função.
Acções:
Definir a função, nome e lista de argumentos
Na lista de argumentos deve ser utilizada a técnica da passagem por
referência de uma variável estruturada. Isto devido a ser necessário
guardar numa variável, que é exterior à função, a informação que se
obtêm do teclado.
No corpo da função é necessário aceder a cada um dos campos da
Programação 2007/2008 DEEC-IST 15
Passagem por referência de
estruturas de dados
Resolução: Código C
voidNovosDados(structFichaProduto *fich,intdimNome) { printf("--- Nova Ficha --- \n");
printf("Nome = ");
fgets((*fich).NomeProd , dimNome, stdin); printf("N_Serie = ");
scanf("%d", &((*fich).N_SerieProd)); printf("N_LoteProd = ");
scanf("%d", &((*fich).N_LoteProd)); printf("Data de Validade (dia/mes/ano) = "); scanf("%d", &((*fich).DataVal.Dia)); scanf("%d", &((*fich).DataVal.Mes)); scanf("%d", &((*fich).DataVal.Ano)); printf("Quantidade = "); scanf("%d", &((*fich).QuantidadeProd)); printf("\n"); }
Parâmetro formal
Passagem por referência,
utilização de um apontador
Atenção:
Neste exemplo não se faz a
validação dos dados de entrada. Por
exemplo o utilizador pode introduzir
números negativos para a data
Programação 2007/2008 DEEC-IST 16
Manipulação de estruturas de
dados
Vamos incorporar as funções e testá-las:
#include <stdio.h>#include <string.h> /* Uso de strcpy */
#include “farmacia.h”/* Contem a definicao das constantes */ /* Contem as estruturas */
/* Contem os prototipos das funcoes */
intmain (void) {
structFichaProduto prod1,
prod2 = {"Anti-gripe", /* Inicializacao de prod2 */
01,21, /* na declaracao da variavel*/ {1,02,2004},
200
};
/* Inicializacao de prod1 campo a campo */ strcpy(prod1.NomeProd,"Tira as Dores");
prod1.N_SerieProd =20; prod1.N_LoteProd =33; prod1.DataVal.Dia =02; prod1.DataVal.Mes =12; prod1.DataVal.Ano =2006; prod1.QuantidadeProd =5000;
Programação 2007/2008 DEEC-IST 17
Manipulação de estruturas de
dados
Vamos incorporar as funções e testá-las (cont.):
MostraFicha(prod1,1);MostraFicha(prod2,2); /* Vamos copiar */
prod2 = prod1; /* Isto é uma atribuicao entre variáveis estruturadas */ MostraFicha(prod2,2);/* Vamos ver o resultado */
NovosDados(&prod2, NOMEDimMAX-1);/* Vamos pedir dados ao utilizador */ MostraFicha(prod2,2); /* Vamos mostrar o que foi armazenado */
/* Por curiosidade */
/* Qual é o endereco da variavel prod2 ? */ printf("Endereço de prod2 = %p\n", (void*) &prod2);
/* Quantos bytes de memória é que prod2 ocupa */ printf("Dimensão de prod2 = %d bytes",sizeof(prod2) );
return0;
}
Para obter o endereço
Manipulação de estruturas de
dados
Vamos ver o resultado:
- Ficha N.1---Nome = Tira as Dores N_Serie = 20 N_LoteProd = 33 Data de Validade = 2/12/2006 Quantidade = 5000 - Ficha N.2 ---Nome = Anti-gripe N_Serie = 1 N_LoteProd = 21 Data de Validade = 1/2/2004 Quantidade = 200 - Ficha N.2 ---Nome = Tira as Dores N_Serie = 20 N_LoteProd = 33 Data de Validade = 2/12/2006 Quantidade = 5000 --- Nova Ficha ---Nome = Melhoral C N_Serie = 01 N_LoteProd = 02
Data de Validade (dia/mes/ano) = 31 02 23456 Quantidade = 999999 - Ficha N.2 ---Nome = Melhoral C N_Serie = 1 N_LoteProd = 2 Data de Validade = 31/2/23456 Quantidade = 999999 Endereco de prod2 = 0x0012ff48 Dimensao de prod2 = 76 bytes
Mas o problema ainda não está completo !
Continua na próxima aula.
Programação 2007/2008 DEEC-IST 19
Estrutura de dados e vectores
Continuando a desenvolver o programa, é necessário:
Definir a variável de suporte ao armazenamento dos dados
dos medicamentos.
Em princípio deve ser utilizado um vector de estruturas.
Apresentar uma lista de opções ao utilizador
Para cada opção deve existir uma função que agrupa as
acções necessárias. Internamente a cada função, podem
existir chamadas a outras funções.
Desenvolver as funções
Já foram desenvolvidas duas funções, uma que apresenta
os dados de uma ficha, e a outra função que permite ler os
dados do teclado e armazená-los numa estrutura.
Programação 2007/2008 DEEC-IST 20
Estrutura de dados e vectores
O programa deve ter uma função que permita apresentar,
listar, as opções que estão disponíveis:
void
MostraOpcoes(
void
){
printf(
"\n---\n"
);
printf(
"Lista de Opcoes \n\n"
);
printf(
"0 - Terminar\n"
);
printf(
"1 - Inserir Produto\n"
);
printf(
"2 - Procurar Produto\n"
);
printf(
"3 - Apagar Produto\n"
);
printf(
"\nOpcao:"
);
Programação 2007/2008 DEEC-IST 21
Estrutura de dados e vectores
O programa deve apresentar uma lista de opções, deve em seguida ler a
opção do utilizador e desencadear as acções necessárias.
Análise das opções:
Terminar
:
O programa termina assim que a opção terminar for seleccionada.
Inserir um Produto
:
É necessário verificar se há espaço livre para um novo produto. Depois
devem ser pedidos os dados do produto, colocando-os na base de dados.
Procurar e Listar um Produto
:
É necessário pedir o dado através do qual se pretende efectuar a procura.
Em seguida é necessário consultar o vector que tem as fichas.
Apagar um Produto
:
É similar a Procurar um Produto com a diferença que se altera uma ficha se
o produto existir.
Estrutura de dados e vectores
A função main deve ser definida colocando em evidência as acções
principais do programa, com chamadas às funções adequadas.
intmain (void) {
structFichaProduto med[PRODNumMAX];
intNumMed;/* Numero de medicamentos */
intoperacao =1, opcao;
LimpaBaseDados(med, &NumMed, PRODNumMAX);
do{ MostraOpcoes(); scanf("%d", &opcao); switch(opcao) { case0: printf(" Fim \n"); operacao =0;/* Fim */ break; case1:
InsereProduto(med, &NumMed, PRODNumMAX);
break; case2: ProcuraProduto(med, PRODNumMAX); break; case3: ApagaProduto(med, &NumMed, PRODNumMAX); break; default:
printf("Opcao invalida \n"); }
}while(operacao);
return0; }
Programação 2007/2008 DEEC-IST 23
Estrutura de dados e vectores
A função LimpaBaseDados tem como finalidade preparar o vector das
fichas de modo a que as fichas estejam limpas para serem utilizadas, faz uso da
função LimpaFicha.
voidLimpaFicha(structFichaProduto *ficha){ (*ficha).NomeProd[0] ='\0'; (*ficha).N_SerieProd =0; (*ficha).N_LoteProd =0; (*ficha).DataVal.Dia =0; (*ficha).DataVal.Mes =0; (*ficha).DataVal.Ano =0; (*ficha).QuantidadeProd =0; } /*---*/
voidLimpaBaseDados(structFichaProduto med[],int*nMed,intmaxV){
inti;
for(i=0; i<maxV; ++i) LimpaFicha(&(med[i]));
*nMed =0;/* Numero de medicamentos armazenados */ }
Programação 2007/2008 DEEC-IST 24
Estrutura de dados e vectores
A função InsereProduto tem como finalidade pedir ao utilizador os
dados de um novo medicamento, colocando-os numa ficha que esteja
vazia. A função para além de procurar uma ficha que esteja vazia
também deve verificar se o número de série do novo produto é único na
base de dados. Este último ponto não é realizado, fica para exercício.
A função InsereProduto faz uso da função ProcuraNSerie para
obter uma ficha vazia. Assume-se que uma ficha que esteja vazia tem o
campo do número de série igual a zero.
Os dados do utilizador são lidos através da função NovosDados. A
Programação 2007/2008 DEEC-IST 25
Estrutura de dados e vectores
Código da função InsereProduto
voidInsereProduto(structFichaProduto med[],int*nMed,intmaxV){
intposicao;
if(*nMed >= maxV) { /* Verifica se ha espaco */ printf("Base de Dados Esgotada\n");
return; }
/* Ha espaco mas e' necessario encontrar uma ficha */ /* que esteja vazia, que tenha o numero de serie <= zero */ posicao = ProcuraNSerie(med, maxV,0);
if(posicao == -1) {
printf("Erro: e' suposto existir espaco\n");
return; }
/* A variavel posicao tem a posicao no vector com a ficha vazia,*/ /* a primeira que encontrou. Vamos pedir dados, utilizar a funcao */ NovosDados(&(med[posicao]), NOMEDimMAX-1);
/* O QUE ACONTECE SE O UTILIZADOR INSERIR UM PRODUTO */
/* COM UM NUMERO DE SERIE DE UM PRODUTO QUE JA ESTA ARMAZENADO ?? */ /* Incrementar o numero de fichas que estão ocupadas */
*nMed +=1;
printf("\nA ficha foi inserida\n"); }
Estrutura de dados e vectores
Código da função ProcuraNSerie
A função percorre o vector das fichas e verifica se existe alguma ficha com o
número de série pretendido. Nesse caso devolve o número inteiro
correspondente à posição no vector e caso contrário devolve o valor -1.
intProcuraNSerie(structFichaProduto med[],intmaxV,intNumSerie){
inti;
for(i=0; i < maxV; ++i) {
if(med[i].N_SerieProd == NumSerie)
return(i); /* Se sucesso */ }
return-1; /* Se nao encontrou */ }
Programação 2007/2008 DEEC-IST 27
Estrutura de dados e vectores
Código da função NovosDados
voidNovosDados(structFichaProduto *fich,intdimNome) {
printf("--- Nova Ficha --- \n"); printf("Nome = ");
do{
fgets((*fich).NomeProd , dimNome, stdin); }while((*fich).NomeProd[0] =='\n');
printf("N_Serie = ");
scanf("%d", &((*fich).N_SerieProd)); printf("N_LoteProd = ");
scanf("%d", &((*fich).N_LoteProd)); printf("Data de Validade (dia/mes/ano) = "); scanf("%d", &((*fich).DataVal.Dia)); scanf("%d", &((*fich).DataVal.Mes)); scanf("%d", &((*fich).DataVal.Ano)); printf("Quantidade = "); scanf("%d", &((*fich).QuantidadeProd)); printf("\n"); } Programação 2007/2008 DEEC-IST 28
Estrutura de dados e vectores
Função MostraFicha
É utilizada para apresentar a informação de um produto. Recebe
uma ficha através do mecanismo de passagem por valor.
void
MostraFicha(
struct
FichaProduto fich,
int
numfich) {
printf(
"--- Ficha N.%d --- \n"
, numfich);
printf(
"Nome = %s\n"
, fich.NomeProd);
printf(
"N_Serie = %d\n"
, fich.N_SerieProd);
printf(
"N_LoteProd = %d\n"
, fich.N_LoteProd);
printf(
"Data de Validade = %d/%d/%d\n"
,
fich.DataVal.Dia, fich.DataVal.Mes, fich.DataVal.Ano);
printf(
"Quantidade = %d\n"
, fich.QuantidadeProd);
}
Programação 2007/2008 DEEC-IST 29
Estrutura de dados e vectores
A função ProcuraProduto
Pede ao utilizador o número de série do produto, efectua uma
procura com a função ProcuraNSerie, e apresenta o resultado se
teve sucesso na procura.
void
ProcuraProduto(
struct
FichaProduto med[],
int
maxV){
int
numSerie, posicao;
/* Procurar com base no numero de serie */
printf(
"Numero de Serie do Produto = "
);
scanf(
"%d"
, &numSerie);
posicao = ProcuraNSerie(med, maxV, numSerie);
if
(posicao == -
1
)
printf(
" Nao existe o produto pretendido\n"
);
else
MostraFicha(med[posicao], posicao);
}
Estrutura de dados e vectores
Função ApagaProduto
É utilizada para apagar um produto da base de dados. O processo de apagar
um produto consiste em procurar a ficha do produto que se pretende apagar
e utilizar a função LimpaFicha. Esta última função é utilizada para inicializar o
vector das fichas quando o programa tem início.
void
ApagaProduto(
struct
FichaProduto med[],
int
*nMed,
int
maxV){
int
numSerie, posicao;
printf(
"Numero de Serie do Produto="
);
scanf(
"%d"
, &numSerie);
posicao = ProcuraNSerie(med, maxV, numSerie);
if
(posicao == -
1
)
printf(
" Nao existe o produto pretendido\n"
);
else
{
LimpaFicha(&(med[posicao]));
*nMed -=
1
;
}
}
Programação 2007/2008 DEEC-IST 31
Estrutura de dados e vectores
Teste ao funcionamento do Programa:
---Lista de Opcoes 0 - Terminar 1 - Inserir Produto 2 - Procurar Produto 3 - Apagar Produto Opcao:1 --- Nova Ficha ---Nome = Sais Vitais
N_Serie = 123 N_LoteProd = 001
Data de Validade (dia/mes/ano) = 02 12 2004 Quantidade = 111
A ficha foi inserida ---Lista de Opcoes 0 - Terminar 1 - Inserir Produto 2 - Procurar Produto 3 - Apagar Produto Opcao:2
Numero de Serie do Produto=123 - Ficha N.0 ---Nome = Sais Vitais
N_Serie = 123 N_LoteProd = 1 Data de Validade = 2/12/2004 Quantidade = 111 ---Lista de Opcoes 0 - Terminar 1 - Inserir Produto 2 - Procurar Produto 3 - Apagar Produto Opcao: Programação 2007/2008 DEEC-IST 32
Estrutura de dados e vectores
Comentários:
Em relação ao programa que foi apresentado há diversas situações que não
foram contempladas e que devem ser abordadas.
Ter o cuidado de testar e validar os dados que são introduzidos pelo utilizador.
Incluir um campo na estrutura de modo a ser possível incluir o preço do
medicamento.
Desenvolver funções que possibilitem a procura de produtos utilizando outros
códigos de procura como por exemplo o nome ou a data de validade.
Desenvolver funções que permitam apresentar uma lista de produtos, mas que
estejam ordenados por ordem crescente de preços.
De salientar que o programa perde a informação que se encontra na base de
dados sempre que o computador tenha uma falha de energia, ou quando se
termina o programa. Para ultrapassar esse problema é necessário
armazenar os dados no disco do computador. É necessário guardar os
dados num ficheiro de texto.
Programação 2007/2008 DEEC-IST 33
Ficheiros
Para preservar os dados é necessário:
Armazenar os dados em disco antes de terminar o programa.
Ler os dados que estão em disco antes de o utilizador começar a
utilizar a base de dados.
No que se refere ao programa devem-se disponibilizar mais duas
opções:
voidMostraOpcoes(void){ printf("\n---\n"); printf("Lista de Opcoes \n\n"); printf("0 - Terminar\n"); printf("1 - Inserir Produto\n"); printf("2 - Procurar Produto\n"); printf("3 - Apagar Produto\n");
printf("4 - Guardar dados em disco \n"); printf("5 - Ler dados do disco \n"); printf("\nOpcao:");
}
Novas opções
Ficheiros - Escrita e Leitura
O programa fica completo incluindo:
As directivas
#include <stdio.h>
#include<string.h>
As instruções seguintes na instrução switch que se encontra na função main
case
4
:
EscDadosFich(med, PRODNumMAX,
"farmacia.dat"
);
break
;
case
5
:
LeDadosFich(med, &NumMed, PRODNumMAX,
NOMEDimMAX-1
,
"farmacia.dat"
);
Programação 2007/2008 DEEC-IST 35
Ficheiros - Escrita
Código da função que permite guardar os dados do vector num ficheiro.
intEscDadosFich(structFichaProduto med[],intmaxV,char*nome) { FILE * fp;inti;
fp = fopen(nome,"w");
if(fp == NULL) {
printf("Erro na abertura do ficheiro %s", nome);
return1; }
for(i=0; i < maxV; i++) { /* Vamos escrever os dados */
if(med[i].N_SerieProd >0) { /* ficha nao vazia */ fprintf(fp,"%s\n", med[i].NomeProd); fprintf(fp,"%d\n", med[i].N_SerieProd); fprintf(fp,"%d\n", med[i].N_LoteProd); fprintf(fp,"%d/%d/%d\n", med[i].DataVal.Dia, med[i].DataVal.Mes, med[i].DataVal.Ano); fprintf(fp,"%d\n", med[i].QuantidadeProd); } } /* fechar o ficheiro */ fclose (fp);
printf("\n Dados guardados\n"); }
Programação 2007/2008 DEEC-IST 36
Ficheiros - Leitura
Código da função que permite ler os dados do ficheiro para o vector.
voidLeDadosFich(structFichaProduto med[],int*nMed,intmaxV,intdimNprod,char*nome) {
FILE * fp;
structFichaProduto ficha;
inti=0;
fp = fopen(nome,"r");
if(fp == NULL) {
printf("Erro na abertura do ficheiro %s", nome);
return; }
while(!feof(fp)) {
char *pc;
if(fgets( ficha.NomeProd, dimNprod,fp) == NULL) { fclose(fp);
return; }
/* Procura o \n na string e faz a substituicao por \0 */
if((pc=strchr(ficha.NomeProd,'\n')) != NULL) *pc ='\0';
Programação 2007/2008 DEEC-IST 37
Ficheiros - Leitura
Código da função
LeDadosFich
(cont.).
if(fscanf(fp,"%d\n", &(ficha.N_SerieProd)) !=1) { printf("Erro no Ficheiro de dados\n ");
fclose(fp);
return; }
if(fscanf(fp,"%d\n", &(ficha.N_LoteProd)) !=1) { printf("Erro no Ficheiro de dados\n ");
fclose(fp);
return; }
if(fscanf(fp,"%d/%d/%d\n", &(ficha.DataVal.Dia),
&(ficha.DataVal.Mes), &(ficha.DataVal.Ano)) !=3) { printf("Erro no Ficheiro de dados\n ");
fclose(fp);
return; }
if(fscanf(fp,"%d\n", &(ficha.QuantidadeProd)) !=1) { printf("Erro no Ficheiro de dados\n ");
fclose(fp);
return; }
Ficheiros - Leitura
Código da função
LeDadosFich
(cont.).
med[i] = ficha; i++;
if(i>= maxV) { /* E ainda nao atingiu o fim do ficheiro */ printf("Base de Dados cheia\n");
fclose (fp); return; } } /* fechar o ficheiro */ fclose (fp); *nMed = i-1;
printf("\n Dados guardados\n"); }
Programação 2007/2008 DEEC-IST 39