bcouto Posted July 6, 2012 at 05:28 PM Report #467753 Posted July 6, 2012 at 05:28 PM (edited) Boas Amigos. Gostaria de obter ajuda acerca do código abaixo inscrito. Tenho de resolver um problema até segunda feira para controlo de empréstimos numa biblioteca. Acontece que quando insiro novos dados, esses mesmos dados são introduzidos correctamente numa lista ligada e quando saio do programa, estes dados passam a ser gravados num ficheiro de texto. Até aqui tudo óptimo, o problema é quando inicio novamente o programa, este não carrega para a lista ligada os dados que foram correctamente gravados no ficheiro.txt. Penso que a abordagem da função, no_emprestimo *Carrega_Emprestimos(no_emprestimo *plistaemp), não é a melhor e faz com a lista ligada apenas mostre correctamente os dados que insiro em cada vez que entro no programa, ficando os do ficheiro de texto desorganizados e inutilizados pela lista ligada . Agradecia imenso a Vossa ajuda. Agradecido, Couto. Aqui fica o código do h.file: #include <stdio.h> #include<stdlib.h> #include<string.h> #include <windows.h> #include <conio.h> #include <tchar.h> #include <locale.h> #include<time.h> typedef struct date{ int dia, mes, ano;} data; typedef struct emprestimo{ char nome[51]; char isbn[18]; data datareq; data dataent; int prazo; } ficha_emprestimo; typedef struct _no_emprestimo{ ficha_emprestimo emp; struct _no_emprestimo *next; }no_emprestimo; no_emprestimo *AdicionaEmprestimo(no_emprestimo *plistaemp) { no_emprestimo *aux; ficha_emprestimo e; int temp; _int64 rawtime; struct tm *r,*d; int classe; if(!(aux=(no_emprestimo *)malloc(sizeof(no_emprestimo)))){ printf("Erro na reserva de memória"); exit(1); } puts("\n***** Insira os dados de emprestimo *****\n"); time (&rawtime); r= localtime ( &rawtime ); printf("Introduza a categoria:"); scanf("%d",&classe); if(classe==0||classe==2) e.prazo=30; if(classe==1||classe==7||classe==8||classe==9) e.prazo=15; if(classe==3||classe==5||classe==6) e.prazo=7; printf("Nome do Requisitante:"); fflush(stdin); gets(e.nome); puts("ISBN:***-*-**-******-* : "); fflush(stdin); gets(e.isbn); printf("Data de Requisição:"); e.datareq.dia=r->tm_mday; e.datareq.mes=r->tm_mon+1; e.datareq.ano=r->tm_year+1900; printf("%d-%d-%d\n",e.datareq.dia,e.datareq.mes,e.datareq.ano); rawtime+=3600*24*e.prazo; d= localtime (&rawtime); printf("Data de Entrega:"); e.dataent.dia=d->tm_mday; e.dataent.mes=d->tm_mon+1; e.dataent.ano=d->tm_year+1900; printf("%d-%d-%d\n",e.dataent.dia,e.dataent.mes,e.dataent.ano); printf("Prazo:%d",e.prazo); aux->emp=e; aux->next=plistaemp; return aux; } void MostraEmprestimo (no_emprestimo *plistaemp) { printf("\nNome: %s",plistaemp->emp.nome); printf("\nIsbn:%s",plistaemp->emp.isbn); printf("\nData de Requisição: %d-%d-%d",plistaemp->emp.datareq.dia,plistaemp->emp.datareq.mes,plistaemp->emp.datareq.ano); printf("\nData de Entrega: %d-%d-%d",plistaemp->emp.dataent.dia,plistaemp->emp.dataent.mes,plistaemp->emp.dataent.ano); printf("\nPrazo:%d",plistaemp->emp.prazo); } void ApresentaEmprestimo(no_emprestimo *plistaemp) { if(plistaemp) while(plistaemp) { MostraEmprestimo(plistaemp); plistaemp=plistaemp->next; } else printf("\n**** LISTA VAZIA ****\n"); system("pause"); } void Guarda_Emprestimo(no_emprestimo *plistaemp) { FILE *fp; if((fp=fopen("emprest.txt","w"))==NULL){printf("Erro na abertura do Ficheiro.\n");exit(1);} if(plistaemp) { while(plistaemp) { fprintf(fp,"\n%s\t",plistaemp->emp.nome); fprintf(fp,"%s\t",plistaemp->emp.isbn); fprintf(fp,"%d/%d/%d\t",plistaemp->emp.datareq.dia,plistaemp->emp.datareq.mes,plistaemp->emp.datareq.ano); fprintf(fp,"%d/%d/%d\t",plistaemp->emp.dataent.dia, plistaemp->emp.dataent.mes, plistaemp->emp.dataent.ano); fprintf(fp,"%d\n",plistaemp->emp.prazo); plistaemp=plistaemp->next; } } fclose(fp); } no_emprestimo *Carrega_Emprestimos(no_emprestimo *plistaemp) { FILE *fp; ficha_emprestimo e; no_emprestimo *aux=plistaemp; if(!(fp=fopen("emprest.txt", "r"))) { printf("Erro %d na abertura do ficheiro - Emprest.txt-"); exit(1); } else { while(!feof(fp)) { if(!(aux=(no_emprestimo *)malloc(sizeof(no_emprestimo)))){printf("Erro na reserva de memoria");exit(1);} fgets(e.nome,49,fp); fgets(e.isbn,17,fp); fscanf(fp,"\t%d-%d-%d\t",&e.datareq.dia,&e.datareq.mes,&e.datareq.ano); fscanf(fp,"\t%d-%d-%d\t",&e.dataent.dia,&e.dataent.mes,&e.dataent.ano); fscanf(fp,"\t%d\t",&e.prazo); aux->emp=e; aux->next=plistaemp; plistaemp=aux; } } fclose(fp); return plistaemp; } void menu() { char k=0; no_emprestimo *inicio=NULL; inicio=Carrega_Emprestimos(inicio); while( k != '0') { system("cls"); puts("******* Biblioteca *******"); puts("1- Adicionar Empréstimo"); puts("2- Mostrar Empréstimos"); puts("0- Sair"); k=getch(); switch (k) { case '1':inicio=AdicionaEmprestimo(inicio); getch(); break; case '2':ApresentaEmprestimo(inicio); break; case'0':Guarda_Emprestimo(inicio); break; default:puts("Opção Invalida"); break; } } getch(); } int main() { menu(); } Edited July 6, 2012 at 05:57 PM by bcouto LP adicionada ao GeSHi
HappyHippyHippo Posted July 6, 2012 at 05:35 PM Report #467756 Posted July 6, 2012 at 05:35 PM (edited) epa ... isso é impossível ler !! @moderador : onde foi parar o post do fórum onde se ensina a usar o geshi ??? PS descubri https://www.portugal-a-programar.pt/topic/6931-tutorial-como-utilizar-o-geshi-codigo-colorido/ Edited July 6, 2012 at 05:36 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
bcouto Posted July 6, 2012 at 05:44 PM Author Report #467758 Posted July 6, 2012 at 05:44 PM já está resolvido o problema do código. Obrigado HappyHippyHippo
HappyHippyHippo Posted July 6, 2012 at 05:47 PM Report #467760 Posted July 6, 2012 at 05:47 PM já está resolvido o problema do código. Obrigado HappyHippyHippo não na sua totalidade ... tenta usar as tags do geshi apresentadas no link que fiz referência IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
bcouto Posted July 6, 2012 at 05:54 PM Author Report #467764 Posted July 6, 2012 at 05:54 PM (edited) Agora sim. Agradecia a ajuda. Edited July 6, 2012 at 05:58 PM by bcouto
HappyHippyHippo Posted July 6, 2012 at 05:57 PM Report #467765 Posted July 6, 2012 at 05:57 PM Assim? xD quase quase na abertura do código escreve "code=c" em ves de ser só "code", dessa forma é feito o syntaxe highlight do código que facilita ainda mais IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
pmg Posted July 6, 2012 at 05:59 PM Report #467766 Posted July 6, 2012 at 05:59 PM void Guarda_Emprestimo(no_emprestimo *plistaemp) { /* ... */ fprintf(fp,"\n%s\t",plistaemp->emp.nome); fprintf(fp,"%s\t",plistaemp->emp.isbn); fprintf(fp,"%d/%d/%d\t",plistaemp->emp.datareq.dia,plistaemp->emp.datareq.mes,plistaemp->emp.datareq.ano); fprintf(fp,"%d/%d/%d\t",plistaemp->emp.dataent.dia, plistaemp->emp.dataent.mes, plistaemp->emp.dataent.ano); fprintf(fp,"%d\n",plistaemp->emp.prazo); /* ... */ } no_emprestimo *Carrega_Emprestimos(no_emprestimo *plistaemp) { /* ... */ fgets(e.nome,49,fp); fgets(e.isbn,17,fp); fscanf(fp,"\t%d-%d-%d\t",&e.datareq.dia,&e.datareq.mes,&e.datareq.ano); fscanf(fp,"\t%d-%d-%d\t",&e.dataent.dia,&e.dataent.mes,&e.dataent.ano); fscanf(fp,"\t%d\t",&e.prazo); /* ... */ } Os fprintf's e os fgets's / fscanf's nao estao coerentes. What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
bcouto Posted July 6, 2012 at 06:03 PM Author Report #467769 Posted July 6, 2012 at 06:03 PM Os fprintf's e os fgets's / fscanf's nao estao coerentes. Qual a sugestão para resolução?
pmg Posted July 6, 2012 at 06:10 PM Report #467773 Posted July 6, 2012 at 06:10 PM (edited) Sugestoes 1) usa uma base de dados 2) usa um substituto de base de dados (sqlite: na realidade um fprintf / fscanf mais potente) 3) faz os prints e os scanfs coerentes, por exemplo nao testado; receio erros de "off-by-one" fprintf(fp, "%49.49s", x->emp.nome); /* ... */ fscanf(fp, "%49c", x->emp.nome); Edited July 6, 2012 at 06:11 PM by pmg What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
HappyHippyHippo Posted July 6, 2012 at 06:12 PM Report #467774 Posted July 6, 2012 at 06:12 PM (edited) torna-las coerentes ... verifica que se estas a escrever num formato, terás de as ler no mesmo formato no teu caso (por exemplo) estas a adicionar o caracter '/' na escrita, logo será esse o caracter que se espera quando efetuas o fscanf, ao contrário do utilizado '-' sqlite: na realidade um fprintf / fscanf mais potente isso é rebaixar em muito as funcionalidades/capacidades do SQLite 😄 Edited July 6, 2012 at 06:11 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
pmg Posted July 6, 2012 at 06:31 PM Report #467779 Posted July 6, 2012 at 06:31 PM Quote do site do sqlite ( http://www.sqlite.org/whentouse.html ) Another way to look at SQLite is this: SQLite is not designed to replace Oracle. It is designed to replace fopen(). Daqui a dizer que é um fprintf / fscanf mais potente é um saltinho 🙂 What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
bcouto Posted July 6, 2012 at 06:41 PM Author Report #467782 Posted July 6, 2012 at 06:41 PM torna-las coerentes ... verifica que se estas a escrever num formato, terás de as ler no mesmo formato no teu caso (por exemplo) estas a adicionar o caracter '/' na escrita, logo será esse o caracter que se espera quando efetuas o fscanf, ao contrário do utilizado '-' isso é rebaixar em muito as funcionalidades/capacidades do SQLite 😄 Nem de uma maneira ou de outra consigo ler para lista ligada somente aquilo que introduzi e como é para um trabalho da escola, não posso aventurar-me em coisas mais avançadas e isto conta metade da avaliação :s Se conseguissem tentar ver qual o problema que se passa com o meu código, testando-o, agradecia :S Porque mesmo usando um só fprintf para escrever e um fscanf para ler, a função não funciona. Acontece que com a minha primeira abordagem ainda conseguia ler algumas coisas, apareciam eram todas baralhadas e nos campos errados da lista ligada :s
HappyHippyHippo Posted July 6, 2012 at 06:42 PM Report #467784 Posted July 6, 2012 at 06:42 PM (edited) Quote do site do sqlite ( http://www.sqlite.org/whentouse.html ) Daqui a dizer que é um fprintf / fscanf mais potente é um saltinho 🙂 isso é descartar todo o texto seguinte onde se verifica que na realidade a intensão do SQLite não é bem essa : Situations Where SQLite Works Well Nem de uma maneira ou de outra consigo ler para lista ligada somente aquilo que introduzi e como é para um trabalho da escola, não posso aventurar-me em coisas mais avançadas e isto conta metade da avaliação :s quando foi dito que tem de ser coerente, isso significa até os '\t' e '\n' porque isso é informação que está no ficheiro e tem de ser lida pelos scanf's Edited July 6, 2012 at 06:42 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
bcouto Posted July 6, 2012 at 08:28 PM Author Report #467803 Posted July 6, 2012 at 08:28 PM (edited) isso é descartar todo o texto seguinte onde se verifica que na realidade a intensão do SQLite não é bem essa : Situations Where SQLite Works Well quando foi dito que tem de ser coerente, isso significa até os '\t' e '\n' porque isso é informação que está no ficheiro e tem de ser lida pelos scanf's void Guarda_Emprestimo(no_emprestimo *plistaemp) { FILE *fp; if((fp=fopen("emprest.txt","a"))==NULL){printf("Erro na abertura do Ficheiro.\n");exit(1);} if(plistaemp) { while(plistaemp) { fprintf(fp,"\n%s\t",plistaemp->emp.nome); fprintf(fp,"%s\t",plistaemp->emp.isbn); fprintf(fp,"%d/%d/%d\t",plistaemp->emp.datareq.dia,plistaemp->emp.datareq.mes,plistaemp->emp.datareq.ano); fprintf(fp,"%d/%d/%d\t",plistaemp->emp.dataent.dia, plistaemp->emp.dataent.mes, plistaemp->emp.dataent.ano); fprintf(fp,"%d\n",plistaemp->emp.prazo); plistaemp=plistaemp->next; } } fclose(fp); } no_emprestimo *Carrega_Emprestimos(no_emprestimo *plistaemp) { FILE *fp; ficha_emprestimo e; no_emprestimo *aux=plistaemp; if(!(fp=fopen("emprest.txt", "r"))) { printf("Erro %d na abertura do ficheiro - Emprest.txt-"); exit(1); } else { while(!feof(fp)) { if(!(aux=(no_emprestimo *)malloc(sizeof(no_emprestimo)))){printf("Erro na reserva de memoria");exit(1);} fgets(e.nome,49,fp); fgets(e.isbn,17,fp); fscanf(fp,"\t%d-%d-%d\t",&e.datareq.dia,&e.datareq.mes,&e.datareq.ano); fscanf(fp,"\t%d-%d-%d\t",&e.dataent.dia,&e.dataent.mes,&e.dataent.ano); fscanf(fp,"\t%d\t",&e.prazo); aux->emp=e; aux->next=plistaemp; plistaemp=aux; } } fclose(fp); return plistaemp; } eu com esta abordagem ainda consigo aceder aos dados, mas todos desorganizados, mas aparecem no monitor, eu queria ter no campo da lista ligada o nome até ao terminador, no campo isbn: o isbn até ao terminador e assim sucessivamente de acordo com o respectivo campo e não consigo arranjar essa abordagem genérica. mais uma vez solicito a vossa ajuda. Edited July 6, 2012 at 08:30 PM by bcouto
HappyHippyHippo Posted July 8, 2012 at 08:15 AM Report #467880 Posted July 8, 2012 at 08:15 AM a razão porque aparece tudo desorganizado deverá ser porque não tomaste em conta do que o pmg te disse: 3) faz os prints e os scanfs coerentes, por exemplo nao testado; receio erros de "off-by-one" fprintf(fp, "%49.49s", x->emp.nome); /* ... */ fscanf(fp, "%49c", x->emp.nome); isso porque o fgets lê tudo o que pode até preencher o buffer ou encontrar um '\n'. logo deve andar a apanhar informação da data IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now