Jump to content

Listas Ligadas. Preencher uma nova lista ligada(b) com dados existentes da lista ligada(a)


Recommended Posts

Posted

Boa tarde e continuação de bom fim-de-semana.

Tenho uma lista ligada de utilizadores com os campos:

-Nome;

-BI;

e queria preencher uma nova lista ligada de compras com os campos:

-Nome; em que este campo: nome tem existir na lista ligada de utilizadores, senão existir não deverá ser feita a inserção.

-Produto;

-Quantia;

Gostaria de saber como resolver este problema da minha nova lista ligada que, obrigatoriamente, só poderá inserir se o referido nome já estiver inserido na lista ligada utilizadores, caso contrário, ele não deverá deixar fazer a inserção da nova lista.

Como resolver este problema?

Posted (edited)

Andas na mesma turma que o blloncoutz?

Ele tem um problema muito parecido ...

Basicamente, verificas se o nome pertence a lista: se pertencer adicionas a compra, se nao pertencer exibes uma mensagem e nao adicionas.

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!

Posted (edited)

A função para preencher a lista ligada de compras antes de fazeres a inserção dos campos "produtos" e "quantia" tem que comparar o "nome" que queremos adicionar com o da lista ligada dos utilizadores, ou seja,

compra testa_utilizador(dados *utilizador, compra *cmp){ /* dados *utilizador representa o ponteiro para a lista ligada dos utilizadores
            * compra *cmp representa o ponteiro para a lista ligada das compras
            */
printf("Introduza o nome do Utilizador: ");
getchar( ); // Para limpar o buffer do teclado
gets(nome);

while(utilizador->seg!=NULL){ // Vamos considerar utilizador->seg o ponteiro para o próximo elemento da lista ligada
 if(strcmp(utilizador->nome,nome)==1) cmp= adicionar_compra(cmp,nome); /* utilizador->nome representa o nome do 
                      * utilizador da 1a lista ligada
                      */
 utilizador=utilizador->seg;
}

printf("Não existe utilizador!!!\n");

return cmp;
}

Esta função testa se existe um determinado utilizador e caso esse exista adiciona-o.

Agora vamos ter que arranjar a função para adicionar a compra, como nada nos foi especificado vamos considerar adicionar à cauda.

compra adicionar_compra(compra *cmp, char *nome){
compra *aux=cmp;

if(cmp==NULL){
 aux=cmp=(compra *)malloc(sizeof(compra));
}
else{
 while(cmp->seg!=NULL) cmp=cmp->seg;
 cmp=(compra *)malloc(sizeof(compra));
}
printf("Produto: ");
getchar();
gets(cmp->produto);

printf("Quantia: ");
scanf("%d",cmp->quantia);

cmp->seg=NULL;

return cmp;
}

Acho que assim tens o problema resolvido.

Edited by pmg
GeSHi adicionado
Posted
 gets(nome);

Nao! Nao uses gets(). E impossiver usar esta funcao com seguranca e existe uma funcao parecida que se pode sibstituir: a funcao fgets().

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!

Posted

Nao! Nao uses gets(). E impossiver usar esta funcao com seguranca e existe uma funcao parecida que se pode sibstituir: a funcao fgets().

Se fizermos a inclusão da biblioteca string.h acho que não se levanta qualquer problema.

Mas podes sempre fazer fgets(nome,sizeof(nome),stdin), mas tens que fazer a inclusão da biblioteca stdio.h

Posted

O prototipo da funcao gets() deixou de fazer parte dos headers standard desde a publicacao do Standard de 2011. Antes dessa publicacao (muitos, para nao dizer todos, compiladores de C compilam codigo de acordo com um Standard anterior) o prototipo da funcao existia no header <stdio.h>. O header <string.h> nao influencia em nada o comportamento (ou falta de comportamento) de nenhuma destas funcoes.

O problema com o gets() e mesmo intrinseco a funcao. Nao ha nada a fazer, excepto deixar de a usar.

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!

Posted

O prototipo da funcao gets() deixou de fazer parte dos headers standard desde a publicacao do Standard de 2011. Antes dessa publicacao (muitos, para nao dizer todos, compiladores de C compilam codigo de acordo com um Standard anterior) o prototipo da funcao existia no header <stdio.h>. O header <string.h> nao influencia em nada o comportamento (ou falta de comportamento) de nenhuma destas funcoes.

O problema com o gets() e mesmo intrinseco a funcao. Nao ha nada a fazer, excepto deixar de a usar.

Tens razão desculpem o lapso 😕 (I'm sorry!!!!!!)

Posted (edited)

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include <windows.h>
#include <conio.h>
#include <tchar.h>
#include <locale.h>
#include<time.h>




/*header file*/
typedef struct date
{
		 int dia, mes, ano;
}
data;

typedef struct socio{
  char nome[51];
  char bi[15];

		 }
ficha_socio;

typedef struct _no_socio{
		 ficha_socio socio;
		 struct _no_socio *seg;
   }no_socio;
typedef struct emprestimo{
		 char nome[51];
		 char isbn[18];
		 data data_req;
		 data data_ent;
		 int prazo;
		 }
ficha_emprestimo;

typedef struct _no_emprestimo
 {
		 ficha_emprestimo emp;
		 struct _no_emprestimo *next;
   }
no_emprestimo;
//actualizar  todos os fgets com gets()

ficha_socio InserirSocio()
{
ficha_socio u;
printf("Introduza o nome do Socio:\n");
fflush(stdin);
gets(u.nome);
size_t blen = strlen(u.nome);
if (u.nome[blen - 1] == '\n')
	   u.nome[--blen] = 0;
printf("Introduza o Bi + num controlo:\n");
fflush(stdin);
gets(u.bi);
size_t len = strlen(u.bi);
if (u.bi[len - 1] == '\n')
	 u.bi[--len] = 0;
return u;
}
no_socio *AdicionaSocio(no_socio *inicio)
{
 no_socio *aux,*plista=inicio,*ant=NULL;
 if(!(aux=(no_socio *)malloc(sizeof(no_socio))))
 {
printf("Erro na reserva de memoria");
exit(1);
 }
 aux->socio=InserirSocio();
 plista->seg=NULL;

return inicio;
}

void MostraSocio (no_socio *plista)
{
 printf("\n");

 printf("Nome: %s\n",plista->socio.nome);

 printf("BI: %s\n",plista->socio.bi);

printf("\n");


}

void ApresentaSocios(no_socio *plista)
   {

		 if(plista)
					   while(plista)
					   {
							  MostraSocio(plista);
							  if(plista!=NULL)
								  plista=plista->seg;
					   }
				else
					   printf("\n**** LISTA VAZIA ****\n");

				}

void Guarda_Socio(no_socio *plistaemp)
{
   FILE *fp;

   if((fp=fopen("utiliz.txt","w+"))==NULL){printf("Erro na abertura do Ficheiro.\n");exit(1);}

   if(plistaemp)
   {
		 while(plistaemp)
		 {

			  fprintf(fp,"%s\n",plistaemp->socio.nome);

			  fprintf(fp,"%s\n",plistaemp->socio.bi);


			  fputs("\n",fp);

			  plistaemp=plistaemp->seg;
		 }
   }
   fclose(fp);
}


no_socio *Carrega_Socios(no_socio *plistaemp)
{
   FILE *fp;

   no_socio *aux;

int i;
if(!(fp=fopen("utiliz.txt", "a+")))

 {
 if(errno != 2)
  {
			  printf("Erro %d na abertura do ficheiro - utiliz.txt-",errno);
			  exit(1);
  }

	}

  else
  {

		 while(!(feof(fp)))
				{
					 if(!(aux=(no_socio *)malloc(sizeof(no_socio)))){printf("Erro na reserva de memoria");exit(1);}



						 fgets(aux->socio.nome,50,fp);
						 if(!feof(fp))
						 {

						   fscanf(fp,"%s\n",aux->socio.bi);
						   size_t len = strlen(aux->socio.nome);
						   if (aux->socio.nome[len - 1] == '\n')
								aux->socio.nome[--len] = 0;
						   size_t str = strlen(aux->socio.bi);
						   if (aux->socio.bi[str - 1] == '\n')
								aux->socio.bi[--str] = 0;


	aux->seg=plistaemp;
	plistaemp=aux;


  }
 }



 }
fclose(fp);

return plistaemp;
}

no_socio *EliminaSocio(no_socio *inicio)
{
 char nome[100];
 no_socio *aux=inicio, *ant=NULL;
 printf("Introduza o nome do utilizador a eliminar: ");
 fflush(stdin);
 gets(nome);
 size_t str = strlen(nome);
 if (nome[str - 1] == '\n')
  nome[--str] = 0;

 while(aux && (strcmp(aux->socio.nome,nome)))
 {
  ant=aux;
  aux=aux->seg;
 }
 if(aux == NULL)

  printf("Utilizador não encontrado");

 else
 {
  if(ant == NULL)

inicio=aux->seg;

  else

 ant->seg=aux->seg;

  free(aux);
  printf("O Utilizador com o nome %s foi eliminado\n", nome);
  }
  system("pause");
  return inicio;
  }


no_emprestimo *adicionar_emprestimo(no_emprestimo *listaemp, char *nome){

  no_emprestimo *aux=listaemp;
  int classe;
  _int64 rawtime;
  struct tm *r,*d;
  time (&rawtime);
  r= localtime ( &rawtime );

if(listaemp==NULL){
 aux=listaemp=(no_emprestimo *)malloc(sizeof(no_emprestimo));
}
else
{
 while(listaemp->next!=NULL)
listaemp=listaemp->next;
listaemp=(no_emprestimo *)malloc(sizeof(no_emprestimo));

}
printf("Introduza a categoria:");
scanf("%d",&classe);
if(classe==0||classe==2)
		listaemp->emp.prazo=30;
if(classe==1||classe==7||classe==8||classe==9)
		listaemp->emp.prazo=15;
if(classe==3||classe==5||classe==6)
		listaemp->emp.prazo=7;
puts("ISBN:***-*-**-******-* : ");
fflush(stdin);
gets(listaemp->emp.isbn);
size_t leng = strlen(listaemp->emp.isbn);
if (listaemp->emp.isbn[leng - 1] == '\n')
   listaemp->emp.isbn[--leng] = 0;
listaemp->emp.data_req.dia=r->tm_mday;
listaemp->emp.data_req.mes=r->tm_mon+1;
listaemp->emp.data_req.ano=r->tm_year+1900;
printf("Data de Requisição:%d-%d-%d\n",listaemp->emp.data_req.dia,listaemp->emp.data_req.mes,listaemp->emp.data_req.ano);
rawtime+=3600*24*listaemp->emp.prazo;
d= localtime (&rawtime);
listaemp->emp.data_ent.dia=d->tm_mday;
listaemp->emp.data_ent.mes=d->tm_mon+1;
listaemp->emp.data_ent.ano=d->tm_year+1900;
printf("Data de Entrega:%d-%d-%d\n",listaemp->emp.data_ent.dia,listaemp->emp.data_ent.mes,listaemp->emp.data_ent.ano);
printf("Prazo:%d\n",listaemp->emp.prazo);  


listaemp->next=NULL;
return aux;
}



no_emprestimo *testa_utilizador(no_socio *listautilizador, no_emprestimo *listaemp){


char nome[51];
printf("Introduza o nome do Utilizador: ");
gets(nome);
size_t len = strlen(nome);
if (nome[len - 1] == '\n')
 nome[--len] = 0;

while(listautilizador->seg!=NULL){
 if(strcmp(listautilizador->socio.nome,nome)==1)
 listaemp= adicionar_emprestimo(listaemp,nome);

  listautilizador=listautilizador->seg;
}

printf("Não existe utilizador!!!\n");

return listaemp;
}



int main()
{
_tsetlocale(LC_ALL, _T("portuguese_portugal"));
char k=0,j=0,z=0,x=0;
/*no_documento *inicio=NULL;*/
no_emprestimo *beg=NULL;
beg=Carrega_Emprestimos(beg);
no_socio *ini=NULL;
ini=Carrega_Socios(ini);
while( k != '0')
{
system("cls");
puts("******* Biblioteca *******");
puts("1- Catálogo");
puts("2- Sócios");
puts("3- Empréstimos");
puts("4- Gravar");
puts("0- SAIR");
k=getch();
switch (k)
{
case '1' :printf("ainda nada");
break;
case '2' :{
 do
{
system("cls");
puts("******* Utilizadores *******");
puts("1- Adicionar Sócio");
puts("2- Mostrar Sócios");
puts("3- Eliminar Sócio");
puts("4- Gravar");
puts("9- Sair");

   j=getch();

switch(j)
{

case'1':printf("*Inserir Utilizador\n*");
  ini=AdicionaSocio(ini);

  getch();
  break;


case'2':printf("*Listagem Utilizadores*\n");
  ApresentaSocios(ini);
  getch();
  break;




case'3':printf("*Eliminar Utilizador*\n");
  ini=EliminaSocio(ini);
  getch();
  break;
case'4':Guarda_Socio(ini);


default:puts("Opção Inválida");




}
}while(j!='9');
break; }

case '3' :{
 while(z!='9')
{
system("cls");
puts("******* Empréstimos *******");
puts("1- Adicionar Empréstimo");
puts("2- Mostrar Empréstimos");
puts("3- Entregar Empréstimo");
puts("4- Listagem fora de prazo");
puts("5- Gravar");
puts("9-Sair");

   z=getch();

switch(z)
{

case'1':printf("*Empréstimos\n*");


 beg=testa_utilizador(ini,beg);
  getch();
  break;


case'2':printf("*Listagem Empréstimos\n*");
  ApresentaEmprestimo(beg);
  getch();
  break;




case'3':printf("*Entregar Empréstimo\n*");
  beg=EntregaEmprestimos(beg);
  getch();
  break;
case'5':Guarda_Emprestimo(beg);
default:puts("Opção Inválida");
 break;






}
 break;  

  }



default : puts("**** OPCAO INVÁLIDA ****");break;
system("pause");
 }
}

Pmg e jasfmonteiro o projecto é este, Gestão de Bibliotecas. Apenas estava simplificar para ver se conseguia chegar lá. Para efectuar um empréstimo o nome a introduzir, tem de existir na lista ligada dos utilizadores, é o ponto fulcral. Não sei se a inserção do empréstimo está correcta depois das dicas que me deram.

beg=testa_utilizador(ini,beg);

Eu postei o projecto todo, porque estou mesmo a nora com isto e já em desespero, e gostava que voces me dissessem o que está a correr mal e o porquê de o case também não estar sincronizado. Tenho de apresentar este projecto terça de manhã, é uma disciplina custosa e gostava que me ajudassem. Se puderem, testem, sff.

Agradecido.
Edited by bcouto
Posted

e por breaks no fim de cada caso na função main ??

PS : isto para não fazer qualquer tipo de comentário à indentação e estruturação do problema ..... meu deus .....

Esse problema já corrigi.

Eu copio o programa correctamente indentado mas quando publico o post, ele transfigura-se.

Só queria mesmo saber como fazer aquilo do aceitar apenas nomes da lista de utilizadores para adicionar um novo empréstimo.

Só me falta mesmo isso.

Agradecido mais uma vez.

Esse problema já corrigi.

Eu copio o programa correctamente indentado mas quando publico o post, ele transfigura-se.

Só queria mesmo saber como fazer aquilo do aceitar apenas nomes da lista de utilizadores para adicionar um novo empréstimo.

Só me falta mesmo isso.

Agradecido mais uma vez.

Com a fórmula que postaram aqui, anteriormente, não consigo na mesma fazer essa funcionalidade.

O nome que introduzo nunca existe :S

E mais uma vez tentei colocar o código normalmente e fica assim :s

Posted

e por breaks no fim de cada caso na função main ??

PS : isto para não fazer qualquer tipo de comentário à indentação e estruturação do problema ..... meu deus .....

Espero que agora esteja muito mais perceptível e me consigam ajudar. Uma boa noite.

Posted

Para que serve a opção "Catologo", na função main().

E já agora o representa ao certo o "int prazo" na estrutura "struct emprestimo".

é o prazo de empréstimo.

A opção Catálogo é para adicionar livros a uma lista ligada, mas isso é a parte, por isso ainda não puz.

Eu só queria adicionar era apenas os nomes da listaligada socios para adicionar um emprestimo à lista ligada empréstimos.

Só é mesmo isso que falta.

Posted (edited)

Estou a tentar resolver o problema que nos proposeste, o que fiz até agora foi:

#include <stdio.h>
#include <string.h>

#define DIM 100
#define CH1 ';'
#define CH2 '\n'

/** ESTRUTURAS **/

struct data_s{
 int dia;
 int mes;
 int ano;
};

typedef struct data_s data;

struct socio_s{
 char nome[DIM];
 int bi;
 struct socio_s *seg;
};

typedef struct socio_s socio;

struct emprestimo_s{
 char nome[DIM];
 char isbn[16];
 data data_req;
 data data_ent;
 int prazo; // Não sei ao certo para o que serve
 struct emprestimo_s *seg;
};

typedef struct emprestimo_s emprestimo;

/** FUNCOES GERAIS **/

int ler_str(char *str1, char *str2, int i, char c){
 int j;

 for(j=0;str1[i]!=c;j++){
   str2[j]=str1[i];
   i++;
 }

 str2[j]='\0';

 return i;
}

/** GERIR CATOLOGOS **/

void gerir_catologo(){
 printf("GERIR CATOLOGOS\n");
 return;
}

/** GERIR SOCIOS **/

/* CARREGA UMA LINHA DO FICHEIRO DE TEXTO PARA UMA ESTRUTURA */
socio carregar_socio(char *str1){
 socio s;
 char str2[200];
 int i=0;

 i=ler_str(str1,str2,i,CH1);
 strcpy(s.nome,str2);

 i++;

 i=ler_str(str1,str2,i,CH2);
 s.bi=atoi(str2);

 return s;
}

/* INSERE UMA ESTRUTURA À CAUDA DA LISTA LIGADA */
socio *inserir_socio(socio *ptr, socio s){
 socio *aux=ptr;

 if(ptr==NULL){
   ptr=aux=(socio *)malloc(sizeof(socio));
 }
 else{
   while(ptr->seg!=NULL) ptr=ptr->seg;
   ptr->seg=(socio *)malloc(sizeof(socio));
   ptr=ptr->seg;
 }

 strcpy(ptr->nome,s.nome);
 ptr->bi=s.bi;
 ptr->seg=NULL;

 return aux;
}

/* CARREGA O FICHEIRO DOS SOCIOS PARA UMA LISTA LIGADA */
socio *carregar_ficheiro_socios(char *nome_ficheiro){
 FILE *f;
 socio s, *ptr=NULL;
 char str[1000];

 if((f=fopen(nome_ficheiro,"rt"))==NULL){
   printf("Erro ao abrir o ficheiro \"%s\".\n",nome_ficheiro);
   return NULL;
 }

 while(fgets(str,sizeof(str),f)!=NULL){
   s=carregar_socio(str);
   ptr=inserir_socio(ptr,s);
 }

 fclose(f);

 return ptr;
}

/* OBTER OS DADOS DE UM SOCIO */
socio obter_socio(){
 socio s;

 printf("Nome do socio: ");
 getchar();
 gets(s.nome);

 printf("BI do socio: ");
 scanf("%d",&(s.bi));

 return s;
}

/* MOSTRA TODOS OS SOCIOS */
void mostra_socios(socio *ptr){
 printf("LISTA DE SOCIOS");
 printf("-------------------------------");

 if(ptr==NULL){
   printf("Nao existem dados.\n");
   return;
 }

 while(ptr!=NULL){
   printf("Nome: %s\n",ptr->nome);
   printf("BI  : %d\n",ptr->bi);
   printf("-------------------------------");

   ptr=ptr->seg;
 }

 return;
}

/* REMOVE UM SOCIO DA LISTA LIGADA */
socio *remove_socio(socio *ptr){

}

/* MENU DE GERIR SOCIOS */
void gerir_socios(){
 socio *ptr;
 char nome_ficheiro[15]="socios.txt"
 int op;

 ptr=carregar_ficheiro_socios(nome_ficheiro);

 while(1){
   printf("******* Utilizadores *******\n");
   printf("1 - Adicionar socio\n");
   printf("2 - Mostrar socios\n");
   printf("3 - Remover socio\n");
   printf("0 - Voltar a BIBLIOTECA\n\n");

   printf("OPCAO: ");
   scanf("%d",&op);

   switch(op){
     case 1 : ptr=inserir_socio(ptr,obter_socio()); break;
     case 2 : mostra_socios(ptr); break;
     case 3 : ptr=remove_socio(ptr); break;
     case 4 : return;
     default: printf("Opcao Invalida\n"); break;
   }
 }
}

/** GERIR EMPRESTIMOS **/

/** MAIN **/

int main(){
 int op;

 while(1){
   printf("******* Biblioteca *******\n");
   printf("1 - Catalogo\n");
   printf("2 - Socios\n");
   printf("3 - Emprestimos\n");
   printf("0 - Sair\n\n");

   printf("OPCAO: ");
   scanf("%d",&op);

   switch(op){
     case 1 : gerir_catologo(); break;
     case 2 : gerir_socios(); break;
     case 3 : gerir_emprestimos(); break;
     case 0 : return 0;
     default: printf("Opcao Invalida!!!\n"); break;
   }
 }
}

Durante a tarde vou tentar acabar de fazer o resto do código.

Edited by pmg
GeSHi adicionado
Posted

Estou a tentar resolver o problema que nos proposeste, o que fiz até agora foi:

#include <stdio.h>
#include <string.h>

#define DIM 100
#define CH1 ';'
#define CH2 '\n'

/** ESTRUTURAS **/

struct data_s{
 int dia;
 int mes;
 int ano;
};

typedef struct data_s data;

struct socio_s{
 char nome[DIM];
 int bi;
 struct socio_s *seg;
};

typedef struct socio_s socio;

struct emprestimo_s{
 char nome[DIM];
 char isbn[16];
 data data_req;
 data data_ent;
 int prazo; // Não sei ao certo para o que serve
 struct emprestimo_s *seg;
};

typedef struct emprestimo_s emprestimo;

/** FUNCOES GERAIS **/

int ler_str(char *str1, char *str2, int i, char c){
 int j;

 for(j=0;str1[i]!=c;j++){
str2[j]=str1[i];
i++;
 }

 str2[j]='\0';

 return i;
}

/** GERIR CATOLOGOS **/

void gerir_catologo(){
 printf("GERIR CATOLOGOS\n");
 return;
}

/** GERIR SOCIOS **/

/* CARREGA UMA LINHA DO FICHEIRO DE TEXTO PARA UMA ESTRUTURA */
socio carregar_socio(char *str1){
 socio s;
 char str2[200];
 int i=0;

 i=ler_str(str1,str2,i,CH1);
 strcpy(s.nome,str2);

 i++;

 i=ler_str(str1,str2,i,CH2);
 s.bi=atoi(str2);

 return s;
}

/* INSERE UMA ESTRUTURA À CAUDA DA LISTA LIGADA */
socio *inserir_socio(socio *ptr, socio s){
 socio *aux=ptr;

 if(ptr==NULL){
ptr=aux=(socio *)malloc(sizeof(socio));
 }
 else{
while(ptr->seg!=NULL) ptr=ptr->seg;
ptr->seg=(socio *)malloc(sizeof(socio));
ptr=ptr->seg;
 }

 strcpy(ptr->nome,s.nome);
 ptr->bi=s.bi;
 ptr->seg=NULL;

 return aux;
}

/* CARREGA O FICHEIRO DOS SOCIOS PARA UMA LISTA LIGADA */
socio *carregar_ficheiro_socios(char *nome_ficheiro){
 FILE *f;
 socio s, *ptr=NULL;
 char str[1000];

 if((f=fopen(nome_ficheiro,"rt"))==NULL){
printf("Erro ao abrir o ficheiro \"%s\".\n",nome_ficheiro);
return NULL;
 }

 while(fgets(str,sizeof(str),f)!=NULL){
s=carregar_socio(str);
ptr=inserir_socio(ptr,s);
 }

 fclose(f);

 return ptr;
}

/* OBTER OS DADOS DE UM SOCIO */
socio obter_socio(){
 socio s;

 printf("Nome do socio: ");
 getchar();
 gets(s.nome);

 printf("BI do socio: ");
 scanf("%d",&(s.bi));

 return s;
}

/* MOSTRA TODOS OS SOCIOS */
void mostra_socios(socio *ptr){
 printf("LISTA DE SOCIOS");
 printf("-------------------------------");

 if(ptr==NULL){
printf("Nao existem dados.\n");
return;
 }

 while(ptr!=NULL){
printf("Nome: %s\n",ptr->nome);
printf("BI  : %d\n",ptr->bi);
printf("-------------------------------");

ptr=ptr->seg;
 }

 return;
}

/* REMOVE UM SOCIO DA LISTA LIGADA */
socio *remove_socio(socio *ptr){

}

/* MENU DE GERIR SOCIOS */
void gerir_socios(){
 socio *ptr;
 char nome_ficheiro[15]="socios.txt"
 int op;

 ptr=carregar_ficheiro_socios(nome_ficheiro);

 while(1){
printf("******* Utilizadores *******\n");
printf("1 - Adicionar socio\n");
printf("2 - Mostrar socios\n");
printf("3 - Remover socio\n");
printf("0 - Voltar a BIBLIOTECA\n\n");

printf("OPCAO: ");
scanf("%d",&op);

switch(op){
  case 1 : ptr=inserir_socio(ptr,obter_socio()); break;
  case 2 : mostra_socios(ptr); break;
  case 3 : ptr=remove_socio(ptr); break;
  case 4 : return;
  default: printf("Opcao Invalida\n"); break;
}
 }
}

/** GERIR EMPRESTIMOS **/

/** MAIN **/

int main(){
 int op;

 while(1){
printf("******* Biblioteca *******\n");
printf("1 - Catalogo\n");
printf("2 - Socios\n");
printf("3 - Emprestimos\n");
printf("0 - Sair\n\n");

printf("OPCAO: ");
scanf("%d",&op);

switch(op){
  case 1 : gerir_catologo(); break;
  case 2 : gerir_socios(); break;
  case 3 : gerir_emprestimos(); break;
  case 0 : return 0;
  default: printf("Opcao Invalida!!!\n"); break;
}
 }
}

Durante a tarde vou tentar acabar de fazer o resto do código.

Muito Obrigado jasfmonteiro.

Vou tentando aplicar o código acima desenvolvido para o meu programa e entretanto fico à espera do resto do código.

Mais uma vez, Muito Agradecido

Estou a tentar resolver o problema que nos proposeste, o que fiz até agora foi:

#include <stdio.h>
#include <string.h>

#define DIM 100
#define CH1 ';'
#define CH2 '\n'

/** ESTRUTURAS **/

struct data_s{
 int dia;
 int mes;
 int ano;
};

typedef struct data_s data;

struct socio_s{
 char nome[DIM];
 int bi;
 struct socio_s *seg;
};

typedef struct socio_s socio;

struct emprestimo_s{
 char nome[DIM];
 char isbn[16];
 data data_req;
 data data_ent;
 int prazo; // Não sei ao certo para o que serve
 struct emprestimo_s *seg;
};

typedef struct emprestimo_s emprestimo;

/** FUNCOES GERAIS **/

int ler_str(char *str1, char *str2, int i, char c){
 int j;

 for(j=0;str1[i]!=c;j++){
str2[j]=str1[i];
i++;
 }

 str2[j]='\0';

 return i;
}

/** GERIR CATOLOGOS **/

void gerir_catologo(){
 printf("GERIR CATOLOGOS\n");
 return;
}

/** GERIR SOCIOS **/

/* CARREGA UMA LINHA DO FICHEIRO DE TEXTO PARA UMA ESTRUTURA */
socio carregar_socio(char *str1){
 socio s;
 char str2[200];
 int i=0;

 i=ler_str(str1,str2,i,CH1);
 strcpy(s.nome,str2);

 i++;

 i=ler_str(str1,str2,i,CH2);
 s.bi=atoi(str2);

 return s;
}

/* INSERE UMA ESTRUTURA À CAUDA DA LISTA LIGADA */
socio *inserir_socio(socio *ptr, socio s){
 socio *aux=ptr;

 if(ptr==NULL){
ptr=aux=(socio *)malloc(sizeof(socio));
 }
 else{
while(ptr->seg!=NULL) ptr=ptr->seg;
ptr->seg=(socio *)malloc(sizeof(socio));
ptr=ptr->seg;
 }

 strcpy(ptr->nome,s.nome);
 ptr->bi=s.bi;
 ptr->seg=NULL;

 return aux;
}

/* CARREGA O FICHEIRO DOS SOCIOS PARA UMA LISTA LIGADA */
socio *carregar_ficheiro_socios(char *nome_ficheiro){
 FILE *f;
 socio s, *ptr=NULL;
 char str[1000];

 if((f=fopen(nome_ficheiro,"rt"))==NULL){
printf("Erro ao abrir o ficheiro \"%s\".\n",nome_ficheiro);
return NULL;
 }

 while(fgets(str,sizeof(str),f)!=NULL){
s=carregar_socio(str);
ptr=inserir_socio(ptr,s);
 }

 fclose(f);

 return ptr;
}

/* OBTER OS DADOS DE UM SOCIO */
socio obter_socio(){
 socio s;

 printf("Nome do socio: ");
 getchar();
 gets(s.nome);

 printf("BI do socio: ");
 scanf("%d",&(s.bi));

 return s;
}

/* MOSTRA TODOS OS SOCIOS */
void mostra_socios(socio *ptr){
 printf("LISTA DE SOCIOS");
 printf("-------------------------------");

 if(ptr==NULL){
printf("Nao existem dados.\n");
return;
 }

 while(ptr!=NULL){
printf("Nome: %s\n",ptr->nome);
printf("BI  : %d\n",ptr->bi);
printf("-------------------------------");

ptr=ptr->seg;
 }

 return;
}

/* REMOVE UM SOCIO DA LISTA LIGADA */
socio *remove_socio(socio *ptr){

}

/* MENU DE GERIR SOCIOS */
void gerir_socios(){
 socio *ptr;
 char nome_ficheiro[15]="socios.txt"
 int op;

 ptr=carregar_ficheiro_socios(nome_ficheiro);

 while(1){
printf("******* Utilizadores *******\n");
printf("1 - Adicionar socio\n");
printf("2 - Mostrar socios\n");
printf("3 - Remover socio\n");
printf("0 - Voltar a BIBLIOTECA\n\n");

printf("OPCAO: ");
scanf("%d",&op);

switch(op){
  case 1 : ptr=inserir_socio(ptr,obter_socio()); break;
  case 2 : mostra_socios(ptr); break;
  case 3 : ptr=remove_socio(ptr); break;
  case 4 : return;
  default: printf("Opcao Invalida\n"); break;
}
 }
}

/** GERIR EMPRESTIMOS **/

/** MAIN **/

int main(){
 int op;

 while(1){
printf("******* Biblioteca *******\n");
printf("1 - Catalogo\n");
printf("2 - Socios\n");
printf("3 - Emprestimos\n");
printf("0 - Sair\n\n");

printf("OPCAO: ");
scanf("%d",&op);

switch(op){
  case 1 : gerir_catologo(); break;
  case 2 : gerir_socios(); break;
  case 3 : gerir_emprestimos(); break;
  case 0 : return 0;
  default: printf("Opcao Invalida!!!\n"); break;
}
 }
}

Durante a tarde vou tentar acabar de fazer o resto do código.

Só não entendi como estão a ser gravados os dados do sócio e do empréstimo, cada um tem de ter o seu ficheiro.txt. que deverá ser carregado para a respectiva lista ligada aquando do arranque do programa.

Posted (edited)

Aqui tens o programa a funcionar para os socios agora so tens de o aplicar para gerir os catalogos e os emprestimos.

Se precisares de mais alguma coisa é só dizeres.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIM 100
#define CH1 ';'
#define CH2 '\n'

/** ESTRUTURAS **/

struct data_s{
 int dia;
 int mes;
 int ano;
};

typedef struct data_s data;

struct socio_s{
 char nome[DIM];
 int bi;
 struct socio_s *seg;
};

typedef struct socio_s socio;

struct emprestimo_s{
 char nome[DIM];
 char isbn[16];
 data data_req;
 data data_ent;
 int prazo; // Não sei ao certo para o que serve
 struct emprestimo_s *seg;
};

typedef struct emprestimo_s emprestimo;

/** FUNCOES GERAIS **/

int ler_str(char *str1, char *str2, int i, char c){
 int j;

 for(j=0;str1[i]!=c;j++){
   str2[j]=str1[i];
   i++;
 }

 str2[j]='\0';

 return i;
}

/** GERIR CATOLOGOS **/

void gerir_catologo(){
 printf("GERIR CATOLOGOS\n");
 return;
}

/** GERIR SOCIOS **/

/* CARREGA UMA LINHA DO FICHEIRO DE TEXTO PARA UMA ESTRUTURA */
socio carregar_socio(char *str1){
 socio s;
 char str2[200];
 int i=0;

 i=ler_str(str1,str2,i,CH1);
 strcpy(s.nome,str2);

 i++;

 i=ler_str(str1,str2,i,CH2);
 s.bi=atoi(str2);

 return s;
}

/* INSERE UMA ESTRUTURA À CAUDA DA LISTA LIGADA */
socio *inserir_socio(socio *ptr, socio s){
 socio *aux=ptr;

 if(ptr==NULL){
   ptr=aux=(socio *)malloc(sizeof(socio));
 }
 else{
   while(ptr->seg!=NULL) ptr=ptr->seg;
   ptr->seg=(socio *)malloc(sizeof(socio));
   ptr=ptr->seg;
 }

 strcpy(ptr->nome,s.nome);
 ptr->bi=s.bi;
 ptr->seg=NULL;

 return aux;
}

/* CARREGA O FICHEIRO DOS SOCIOS PARA UMA LISTA LIGADA */
socio *carregar_ficheiro_socios(char *nome_ficheiro){
 FILE *f;
 socio s, *ptr=NULL;
 char str[1000];

 if((f=fopen(nome_ficheiro,"rt"))==NULL){
   printf("Erro ao abrir o ficheiro \"%s\".\n",nome_ficheiro);
   return NULL;
 }

 while(fgets(str,sizeof(str),f)!=NULL){
   s=carregar_socio(str);
   ptr=inserir_socio(ptr,s);
 }

 fclose(f);

 return ptr;
}

/* OBTER OS DADOS DE UM SOCIO */
socio obter_socio(){
 socio s;

 printf("Nome do socio: ");
 getchar();
 gets(s.nome);

 printf("BI do socio: ");
 scanf("%d",&(s.bi));

 return s;
}

/* MOSTRA TODOS OS SOCIOS */
void mostra_socios(socio *ptr){
 printf("LISTA DE SOCIOS");
 printf("-------------------------------");

 if(ptr==NULL){
   printf("Nao existem dados.\n");
   return;
 }

 while(ptr!=NULL){
   printf("Nome: %s\n",ptr->nome);
   printf("BI  : %d\n",ptr->bi);
   printf("-------------------------------");

   ptr=ptr->seg;
 }

 return;
}

/* REMOVE UM SOCIO DA LISTA LIGADA */
/* Esta funcao pode conter alguns erros*/
socio *remove_socio(socio *ptr){
 char nome[200];
 socio *aux=ptr;
 socio *aux2=ptr->seg;

 if(ptr==NULL){
   printf("A lista esta vazia");
   return NULL;
 }

 printf("Nome do socio a remover: ");
 getchar();
 gets(nome);

 if(strcmp(nome,ptr->nome)){
   p=p->seg;
   free(aux);
   return ptr;
 }
 while(aux2->seg!=NULL){
   if(strcmp(aux->seg,nome)){
     aux->seg=aux2->seg;
     free(aux2);
     return ptr;
   }
   aux=aux->seg;
   aux2=aux2->seg;
 }
 printf("Nao existe nenhum socio com este nome (\"%s\")\n",nome);
 return ptr;
}

/* GUARDA A LISTA LIGADA NUM FICHEIRO DE TEXTO */
socio *guarda_ficheiro_socio(socio *ptr, char *nome_ficheiro){
 FILE *f;
 socio *aux;

 if((f=fopen(nome_ficheiro,"wt"))==NULL){
   printf("Erro ao guardar o ficheiro \"%s\".\n",nome_ficheiro);
   return NULL;
 }

 while(ptr!=NULL){
   fscanf(f,"%s;%d\n",ptr->nome,ptr->bi);
   aux=p->seg;
   free(ptr);
   ptr=aux;
 }

 return NULL;
}

/* MENU DE GERIR SOCIOS */
void gerir_socios(){
 socio *ptr;
 char nome_ficheiro[15]="socios.txt"
 int op;

 ptr=carregar_ficheiro_socios(nome_ficheiro);

 while(1){
   printf("******* Utilizadores *******\n");
   printf("1 - Adicionar socio\n");
   printf("2 - Mostrar socios\n");
   printf("3 - Remover socio\n");
   printf("0 - Voltar a BIBLIOTECA\n\n");

   printf("OPCAO: ");
   scanf("%d",&op);

   switch(op){
     case 1 : ptr=inserir_socio(ptr,obter_socio()); break;
     case 2 : mostra_socios(ptr); break;
     case 3 : ptr=remove_socio(ptr); break;
     case 4 : ptr=guarda_ficheiro_socio(ptr,nome_ficheiro);return;
     default: printf("Opcao Invalida\n"); break;
   }
 }
}

/** GERIR EMPRESTIMOS **/

/* Para fazer a gestao dos emprestimos apenas tens que fazer a adapcao do modelo apresentado acima,
* ou seja, a gestao dos socios
*/

void gerir_emprestimos(){
 printf("GERIR EMPRESTIMOS\n");
 return;
}

/** MAIN **/

int main(){
 int op;

 while(1){
   printf("******* Biblioteca *******\n");
   printf("1 - Catalogo\n");
   printf("2 - Socios\n");
   printf("3 - Emprestimos\n");
   printf("0 - Sair\n\n");

   printf("OPCAO: ");
   scanf("%d",&op);

   switch(op){
     case 1 : gerir_catologo(); break;
     case 2 : gerir_socios(); break;
     case 3 : gerir_emprestimos(); break;
     case 0 : return 0;
     default: printf("Opcao Invalida!!!\n"); break;
   }
 }
}
Edited by pmg
GeSHi adicionado
Posted

o bcouto deve estar contente por ter um código a funcionar (aparentemente) no entanto não aprender nada

o por causa disso vou-me dar ao trabalho de analisar o código apresentado

int ler_str(char *str1, char *str2, int i, char c){
 int j;

 for(j=0;str1[i]!=c;j++){
   str2[j]=str1[i];
   i++;
 }

 str2[j]='\0';

 return i;
}

isto é algum modelo manual de usar o strtok ? é só complicar

socio *inserir_socio(socio *ptr, socio s){
 socio *aux=ptr;

 if(ptr==NULL){
   ptr=aux=(socio *)malloc(sizeof(socio));
 }
 else{
   while(ptr->seg!=NULL) ptr=ptr->seg;
   ptr->seg=(socio *)malloc(sizeof(socio));
   ptr=ptr->seg;
 }

 strcpy(ptr->nome,s.nome);
 ptr->bi=s.bi;
 ptr->seg=NULL;

 return aux;
}

se a lista não for vazia, qual o valor que retorna ? é sempre a cabeça da lista. não é um procedimento habitual. o mais habitual é retornar o elemento criado.

se o código for coerente com este pormenor, não existe problema

 printf("Nome do socio: ");
 getchar();
 gets(s.nome);

 printf("BI do socio: ");
 scanf("%d",&(s.bi));

usar o gets, apesar de já te terem dito para não o usares ...

não efetuas nenhuma verificação do sucesso de leitura de dados, se uns dedos gordos inserirem algo estranho estoira o programa completamente

(na realidade ainda só vi uma verificação, na abertura do ficheiro, nem a leitura dos dados do ficheiro são verificados)

 while(ptr!=NULL){
   fscanf(f,"%s;%d\n",ptr->nome,ptr->bi);
   aux=p->seg;
   free(ptr);
   ptr=aux;
 }

o que é feito do fprintf ???

porque que gravar os dados em ficheiro leva ao apagar os dados em memória ??

isto foi que encontrei por alto ... não sei o que encontraria se colocasse o código num editor e tentasse correr

  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Posted
Em 23/07/2012 às 20:31, HappyHippyHippo disse:

o bcouto deve estar contente por ter um código a funcionar (aparentemente) no entanto não aprender nada

o por causa disso vou-me dar ao trabalho de analisar o código apresentado


int ler_str(char *str1, char *str2, int i, char c){
 int j;

 for(j=0;str1[i]!=c;j++){
str2[j]=str1[i];
i++;
 }

 str2[j]='\0';

 return i;
}
 

isto é algum modelo manual de usar o strtok ? é só complicar


socio *inserir_socio(socio *ptr, socio s){
 socio *aux=ptr;

 if(ptr==NULL){
ptr=aux=(socio *)malloc(sizeof(socio));
 }
 else{
while(ptr->seg!=NULL) ptr=ptr->seg;
ptr->seg=(socio *)malloc(sizeof(socio));
ptr=ptr->seg;
 }

 strcpy(ptr->nome,s.nome);
 ptr->bi=s.bi;
 ptr->seg=NULL;

 return aux;
}
 

se a lista não for vazia, qual o valor que retorna ? é sempre a cabeça da lista. não é um procedimento habitual. o mais habitual é retornar o elemento criado.

se o código for coerente com este pormenor, não existe problema


 printf("Nome do socio: ");
 getchar();
 gets(s.nome);

 printf("BI do socio: ");
 scanf("%d",&(s.bi));
 

usar o gets, apesar de já te terem dito para não o usares ...

não efetuas nenhuma verificação do sucesso de leitura de dados, se uns dedos gordos inserirem algo estranho estoira o programa completamente

(na realidade ainda só vi uma verificação, na abertura do ficheiro, nem a leitura dos dados do ficheiro são verificados)


 while(ptr!=NULL){
fscanf(f,"%s;%d\n",ptr->nome,ptr->bi);
aux=p->seg;
free(ptr);
ptr=aux;
 }
 

o que é feito do fprintf ???

porque que gravar os dados em ficheiro leva ao apagar os dados em memória ??

isto foi que encontrei por alto ... não sei o que encontraria se colocasse o código num editor e tentasse correr

Em primeiro lugar, quero-me desculpar pelos erros que o meu código pode ter, a realidade é que eu não o tinha testado.

Em segundo, desconhecia por completo a função strtok, a verdade é que sou apenas um aluno do 1º ano de Engenharia Informática.

Em terceiro, a utilização do gets já é um hábito, mas a verdade é que ainda não percebo porque é que não se recomenda a utilização desta função.

Em quarto, fcanf mas é que estava a pensar, HappyHippyHippo tens toda a razão (mas errar é humano).

Eu já tentei compilar o meu código e encontrei alguns erros, mas são coisas simples de resolver como, por exemplo, trocar 'p' por 'ptr'.

Quero pedir mais uma vez as minhas mais sinceras desculpas, sou apenas um rapaz que gosta de programar, mas que ainda está no inicio desta longa jornada. 🙂

Posted

Quero pedir mais uma vez as minhas mais sinceras desculpas, sou apenas um rapaz que gosta de programar, mas que ainda está no inicio desta longa jornada. 🙂

a tua dedicação em programação é de louvar, ainda mais se pretendes ajudar. o problema não está propriamente no erros de código, porque como disseste, errar é humano. o problema é no entregar a solução de mão beijada. é bom para elucidar nos conceitos que a pessoa não sabe ou tem uma ideia errada o que não era este caso.

boa programação

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

a verdade é que ainda não percebo porque é que não se recomenda a utilização [do gets()].

Porque é impossivel usar gets() com seguranca.

Nao ha maneira nenhuma de limitar a escrita de bytes fora do espaco reservado.

int foo(void) {
   char buffer[100];
   // gets(buffer); // é impossivel impedir o utilizador de escrever mais de 100 bytes no buffer
   // scanf("%s", buffer); // é impossivel impedir o utilizador de escrever mais de 100 bytes no buffer
   scanf("%99s", buffer); // ok!
   fgets(buffer, sizeof buffer, stdin); // ok!
}

Edit: mais um motivo para deixar de usar o gets():

Esta funcao deixou de estar definida pelo ultimo Standard (de Dezembro de 2011). Quando todos os compiladores adoptarem este Standard o codigo que usa gets deixa de poder ser compilado. Ate la, a medida que os compiladores vao sendo actualizados, o codigo vai sendo cada vez menos portavel.

Edited by pmg
a funcao gets() deixou de estar definida no Standard

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!

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