• Nenhum resultado encontrado

Noção de estrutura de dados

N/A
N/A
Protected

Academic year: 2021

Share "Noção de estrutura de dados"

Copied!
20
0
0

Texto

(1)

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.

(2)

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

(3)

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

(4)

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

(5)

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

(6)

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

(7)

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

(8)

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;

(9)

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.

(10)

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:"

);

(11)

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

(12)

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

(13)

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 */ }

(14)

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);

}

(15)

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

;

}

}

(16)

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.

(17)

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"

);

(18)

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';

(19)

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"); }

(20)

Programação 2007/2008 DEEC-IST 39

Ficheiro - Leitura



Na função LeDadosFich:



A função fgets é utilizada para ler uma linha de caracteres

(sequência de caracteres incluindo o espaço e o \n), No entanto é

necessário ter o cuidado de retirar o \n. Isso é conseguido

utilizando a função strchr cujo protótipo está no ficheiro string.h. A

função devolve um apontador não nulo para o local da primeira

ocorrência do carácter que se procura, se o carácter for

encontrado.



Existe a preocupação em realizar o teste ao valor de retorno das

funções fscanf de modo a verificar se as fichas estão completas.



Na função fscanf, na string de formatação para além dos

caracteres formatadores também são colocados / e \n. Isso permite

indicar ao fscanf que deve procurar e ler esses caracteres de modo

a que não perturbem a conversão de dados.

Referências

Documentos relacionados

Importa notar que tanto o excesso de açúcar, gorduras e sal quanto a alta densidade energética e a falta de fibras são atributos intrínsecos dos alimentos ultraprocessados na

- Acham que são merecedores de tudo - Não sabem se esforçar para conseguir algo - Não sabem como agir em situações adversas.. - São criados por pais narcisistas, que competem entre

Mais uma vez, o aluno usará a atenção para realizar esta atividade e por fim, poderão colorir de modo que trabalhe diretamente com a coordenação motora fina... Nesta atividade

Acaso não seja possível o pagamento de todos os credores titulares de créditos entre R$ 5.000,01 (cinco mil e um centavo) até R$ 7.500,00, em razão de o valor adquirido com

Concentração de determinada substância, acima da qual podem ocorrer alterações prejudiciais à qualidade do solo e da água subterrânea VALOR DE PREVENÇÃO -

Os motins na América Portuguesa tanto quanto na Espanhola derivam do colapso das formas acomodativas - como será melhor explicado à frente -, ou melhor dizendo, do rompimento

O recurso à nação como narração enfatiza a insistência do poder político e a autoridade cultural naquilo que Derrida descreve “o excesso irredutível do sintático sobre

As dificuldades de se atingir esta pretendida isonomia entre os concorrentes certamente não são devidas à cor do indivíduo mas sim, como tão bem indicas no artigo, à pobreza