Jump to content
bcouto

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

Recommended Posts

bcouto

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

Share this post


Link to post
Share on other sites
HappyHippyHippo

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

Share this post


Link to post
Share on other sites
HappyHippyHippo

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

Share this post


Link to post
Share on other sites
pmg

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!

Share this post


Link to post
Share on other sites
bcouto

Os fprintf's e os fgets's / fscanf's nao estao coerentes.

Qual a sugestão para resolução?

Share this post


Link to post
Share on other sites
pmg

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!

Share this post


Link to post
Share on other sites
HappyHippyHippo

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

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
pmg

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!

Share this post


Link to post
Share on other sites
bcouto

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

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

Share this post


Link to post
Share on other sites
HappyHippyHippo

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

Share this post


Link to post
Share on other sites
bcouto

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

Share this post


Link to post
Share on other sites
HappyHippyHippo

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • 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.