bcouto Posted July 22, 2012 at 05:43 PM Report #469653 Posted July 22, 2012 at 05:43 PM 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?
pmg Posted July 22, 2012 at 06:17 PM Report #469656 Posted July 22, 2012 at 06:17 PM (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 July 22, 2012 at 06:18 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!
jasfmonteiro Posted July 22, 2012 at 06:17 PM Report #469657 Posted July 22, 2012 at 06:17 PM (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 July 22, 2012 at 07:28 PM by pmg GeSHi adicionado
pmg Posted July 22, 2012 at 06:22 PM Report #469658 Posted July 22, 2012 at 06:22 PM 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!
jasfmonteiro Posted July 22, 2012 at 06:38 PM Report #469661 Posted July 22, 2012 at 06:38 PM 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
pmg Posted July 22, 2012 at 07:32 PM Report #469666 Posted July 22, 2012 at 07:32 PM 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!
jasfmonteiro Posted July 22, 2012 at 08:39 PM Report #469674 Posted July 22, 2012 at 08:39 PM 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!!!!!!)
bcouto Posted July 22, 2012 at 11:22 PM Author Report #469696 Posted July 22, 2012 at 11:22 PM (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 July 23, 2012 at 12:18 AM by bcouto
HappyHippyHippo Posted July 22, 2012 at 11:27 PM Report #469699 Posted July 22, 2012 at 11:27 PM (edited) 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 ..... Edited July 22, 2012 at 11:28 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
bcouto Posted July 22, 2012 at 11:53 PM Author Report #469701 Posted July 22, 2012 at 11:53 PM 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
bcouto Posted July 23, 2012 at 12:10 AM Author Report #469702 Posted July 23, 2012 at 12:10 AM 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.
jasfmonteiro Posted July 23, 2012 at 08:49 AM Report #469716 Posted July 23, 2012 at 08:49 AM (edited) 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". Edited July 23, 2012 at 09:00 AM by jasfmonteiro
bcouto Posted July 23, 2012 at 11:00 AM Author Report #469738 Posted July 23, 2012 at 11:00 AM 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.
jasfmonteiro Posted July 23, 2012 at 11:10 AM Report #469740 Posted July 23, 2012 at 11:10 AM (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 July 23, 2012 at 11:31 AM by pmg GeSHi adicionado
bcouto Posted July 23, 2012 at 04:55 PM Author Report #469779 Posted July 23, 2012 at 04:55 PM 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.
jasfmonteiro Posted July 23, 2012 at 06:17 PM Report #469796 Posted July 23, 2012 at 06:17 PM (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 July 23, 2012 at 06:18 PM by pmg GeSHi adicionado
HappyHippyHippo Posted July 23, 2012 at 07:31 PM Report #469808 Posted July 23, 2012 at 07:31 PM 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 1 Report IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
jasfmonteiro Posted July 23, 2012 at 08:50 PM Report #469817 Posted July 23, 2012 at 08:50 PM 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. 🙂
HappyHippyHippo Posted July 23, 2012 at 09:04 PM Report #469820 Posted July 23, 2012 at 09:04 PM 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 Portugol Plus
pmg Posted July 23, 2012 at 09:11 PM Report #469822 Posted July 23, 2012 at 09:11 PM (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 July 23, 2012 at 09:18 PM 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!
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