Jump to content

Carregamento de um Ficheiro de Texto para uma Lista Ligada! Ajuda Urgente


bcouto
 Share

Recommended Posts

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 by bcouto
LP adicionada ao GeSHi
Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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 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!

Link to comment
Share on other sites

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 by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

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 by bcouto
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.