• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

DanielPT

Problema a gravar e a ler estruturas de um ficheiro

11 mensagens neste tópico

Boas, sou novo aqui acabei de me registar, encontrei este forum a pesquisar no google.

Bem, é o seguinte estou a terminar de fazer um mini projecto de programação do primeiro ano de eng. informática, que é fazer um programa de gestão de um aeroporto, criar clientes, voos, reservas, ....

Uma das coisas pedidas é que guardemos as estruturas num ficheiro em binário, e o leia-mos (load & save). Mas não domino esta parte da matéria e não estou a conseguir. Estou a usar isto:

typedef struct _cliente *liga;              
typedef struct _cliente
{
char nome[25], morada[25], email[25], telefone[15];
int fichanum, BI;
liga proximo;
}
cliente;
liga cabeca;

void gravarclientes(liga l) //Função que recebe uma estrutura
{
     FILE *f;
     f=fopen("clientes.txt","wb");
     fseek (f, 0L, SEEK_SET);
     
     while (l) //enquanto a estrutura nao for nula ele vai indo de estrutura em estrutura e vai gravando os dados num ficheiro
     {
           if(l->fichanum!=0) //esta comparação é porque eu tenho um cliente criado a 0 e nao quero que ele seja escrito
		{
                fwrite(&l,sizeof(struct _cliente), 1, f); //suposta função para escrever
            }
		l=l->proximo; //passar para o proximo elemento da lista
     }
     fclose(f);
}

void lerclientes(liga l) //Função que recebe uma estrutura
{
     FILE *f;

     f=fopen("clientes.txt","wb");
     fseek (f, 0L, SEEK_SET);
     
     l=(liga) malloc(sizeof(cliente));   //aloca espaço na memoria para uma nova estrutura
// a partir daqui o que eu pretendia era que fossem colocados os dados na estrutra
     fread(&l->fichanum,sizeof(struct _cliente), 1, f);
     fread(&l->nome,sizeof(struct _cliente), 1, f);
     fread(&l->morada,sizeof(struct _cliente), 1, f);
     fread(&l->telefone,sizeof(struct _cliente), 1, f);
     fread(&l->email,sizeof(struct _cliente), 1, f);
     fread(&l->BI,sizeof(struct _cliente), 1, f);
     fclose(f);
     l->proximo=cabeca; //ponteiro para ligar a estrutura
     cabeca=l;
}

desde ja agradeço

NOTA: Estou a usar listas ligadas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

1) Tens um botãozinho que te ajuda a formatar o código, usa-o para ficar mais fácil de entender.

2) Aqui ninguém é bruxo, apresentar código não chega... Sugiro-te a explicares detalhadamente o teu problema, o que pretendes fazer, o que não consegues, o que já tentaste, etc...

3) Se não fores da Universidade do Minho és um palerma (no hard feelings :confused:)

3) Não tenho mais nada a reclamar...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Quando disse "explicares detalhadamente o problema" não me referia a comenta-lo. O pessoal que te souber ajudar, de certeza que eprcebe o que faz cada linha do teu código. O que quis dizer foi para explicares em que é que o teu problema consiste.

"não estou a conseguir" não explica qual é o problema e o que raio é que não estás a conseguir... Eu (assim como outros) podem não ter tempo nem paciência para estar a interpretar o teu código, tentar perceber o que ele faz para te puder ajudar. Se queres ajuda, explica o que é que estas a tentar fazer e o que é que não estas a conseguir fazer, onde é que te esta a dar problemas, o que é que te esta a falhar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mas eu não sei onde é que estou a ter problemas porque o programa compila e corre, como eu disse antes não domino esta parte da matéria, escrever e ler de ficheiros, tipo o que eu quero fazer é guardar num ficheiro os dados da estrutura, nome do cliente, a morada, o telefone, etc... e depois quero ler e criar novamente a estrutura do cliente com os respectivos dados, e como o objectivo é escrever em binário usei o fwrite e o fread. O que está a acontecer é que a estrutura criada depois de ler fica com valores estranhos, valores que supostamente já estavam na memória, até porque por exemplo na morada do cliente fica isto: ows\System32\windowspowershell\v1.0\ etc...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Com esse comentário já conseguis-te explicar mais alguma coisa. Já sabemos qual é a ideia do do código e o que está a acontecer (mais ao menos), isso é o que deves tentar explicar logo de ínicio. É que mais difícil do que descobrir um erro é tentar perceber o que um pedaço de código faz.

Já agora o primeiro valor lê correcto?

Assim de repente, tu quando lês com

fread(&l->fichanum,sizeof(struct _cliente), 1, f);

estás a ler um pedaço de informação do tamanho de um cliente. Se quiseres guardar toda essa informação tens que receber num cliente e não num dos seus campos. Por exemplo substituindo &l->fichanum papenas por &l. Desse modo ficas com &l todo carrregado e as outras linhas são desnecessárias.

Já agora quando fazes typedef por exemplo aí ao cliente, escusas de usar o struct a partir daí. Não precisas de fazer struct _cliente, só cliente tem o mesmo efeito. Aliás tu usas isso quando alocas espaço para l.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ja tentei isso mas com isso o que acontece é que o programa crasha vou por aqui o codigo que eu tinha dessa forma:

void lerclientes(liga l)
{
     FILE *f;

     f=fopen("clientes.txt","rb");
     if(f!=NULL)
     {
             fseek (f, 0L, SEEK_SET);
             
           	 l=(liga) malloc(sizeof(cliente)); 
             fread(&l,sizeof(cliente), 1, f);
             fclose(f);
             l->proximo=cabeca; //ponteiro para ligar a estrutura
        	 cabeca=l;
    }
     
}

void gravarclientes(liga l)
{
     FILE *f;
     f=fopen("clientes.txt","wb");
     fseek (f, 0L, SEEK_SET);
     
     while (l)
     {
           if(l->fichanum!=0)
         {
                 fwrite(&l,sizeof(cliente), 1, f);
            }
         l=l->proximo;
     }
     fclose(f);
}

outra coisa tive a pensar e tipo isto mesmo que funcione só vai importar 1 struct, eu devia por um ciclo para enquanto houver coisas para ler para estar sempre a importar novas structs, mas não faço ideia de como saber se ainda há ou não coisas para ler.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já verificas-te se a escrever para o ficheiro está a funcionar? Já agora onde crasha?

Outra coisa é que acho que os fseek que tens por aí não são necessários. Por que tu pões o indicador de posição sempre no ínicio.

Quanto a ler várias estruturas. Se souberes que o ficheiro apenas vai ter estruturas desse tipo podes fazer usar o feof para verificar se já chegas-te ao fim do ficheiro.

while( !feof( file ) )
{
    // código aqui
}

Se pode ter outras informações, ou mesmo sem elas, podes criar uma espécie de cabeçalho. Por exemplo os primeiros 4 bytes, que é o tamanho de um inteiro, do ficheiro serem o número de estruturas existentes num ficheiro. Desse modo só tinhas que fazer um for e ler lá dentro.

Dá uma vista de olhos em http://www.cplusplus.com/reference/clibrary/cstdio/ no menu lateral tens várias funções que te podem dar jeito, como a feof por exemplo.

[/code]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

bem pelos vistos o problema estava no "&" no fread e no fwrite mas agora ainda não consegui põr a ler enquanto tiver o que ler, não percebi como a função que disseste funciona, coloquei-a no meu programa e fica um while infinito.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

consegui resolver tudo depois eu posto o código a funcionar para quem tiver com o mesmo problema poder resolvê-lo

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

bem pessoal tal como disse vou postar agora o código a funcionar, é incrível perdi 2 dias à conta disto tudo por causa de uma caractere, este: & .  :wallbash:

É muito frustante, mas pronto.

Segue o código a funcionar obrigado pela ajuda:

void lerclientes(liga l)
{
     FILE *f;
     int ler=1;

     f=fopen("clientes.dat","rb");
     if(f!=NULL)
     {
         while (1)
         {
           	 l=(liga) malloc(sizeof(cliente)); 
             ler=fread(l,sizeof(cliente), 1, f);
             if(ler==0)
             {
                       free(l);
                       break;
             }
           	 if(l->fichanum > numerocliente)
        	 {
                   numerocliente=l->fichanum;
             }
             l->proximo=cabeca; //ponteiro para ligar a estrutura
        	 cabeca=l;
          }    
     }
     
    //Apaga o elemento 0.
eliminarCliente(cabeca, 0);

//Cria o elemento 0.
l=(liga) malloc(sizeof(cliente));
if (l != NULL)
{
	(l->fichanum)=0;
	(l->BI)=0;
	l->proximo=cabeca;
	cabeca=l;
	system("cls");
}
    
    fclose(f); 
}


void gravarclientes(liga l)
{
     FILE *f;
     f=fopen("clientes.dat","wb");
     while (l)
     {
         if(l->fichanum!=0)
         {
            fwrite(l,sizeof(cliente), 1, f);
		l=l->proximo;
         }
         else
         {
             l=l->proximo;
         }
     }
     fclose(f);
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora