Problema a gravar e a ler estruturas de um ficheiro - C - Portugal-a-Programar
Problema a gravar e a ler estruturas de um ficheiro
Por DanielPT, 12 de Junho de 2009 em C
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;
char nome[25], morada[25], email[25], telefone[15];
int fichanum, BI;
liga proximo;
liga cabeca;
void gravarclientes(liga l) //Função que recebe uma estrutura
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
void lerclientes(liga l) //Função que recebe uma estrutura
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);
l->proximo=cabeca; //ponteiro para ligar a estrutura
cabeca=l;
NOTA: Estou a usar listas ligadas.
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 )
3) Não tenho mais nada a reclamar...
pronto acho que já melhor
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.
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...
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
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.
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)
f=fopen("clientes.txt","rb");
l=(liga) malloc(sizeof(cliente));
fread(&l,sizeof(cliente), 1, f);
void gravarclientes(liga l)
if(l->fichanum!=0)
fwrite(&l,sizeof(cliente), 1, f);
l=l->proximo;
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.
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.
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.
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.
consegui resolver tudo depois eu posto o código a funcionar para quem tiver com o mesmo problema poder resolvê-lo
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: