Edu123 Posted December 30, 2015 at 11:32 AM Report #591133 Posted December 30, 2015 at 11:32 AM Olá. Eu tenho um trabalho para a cadeira de programação e precisava de ajuda com uma coisa; Já fiz as estruturas e queria, de certa forma, "integrá-las" como submenus (junto diagrama). Podem me ajudar? obrigado. http://postimg.org/image/po3mj3n6b/
apocsantos Posted December 30, 2015 at 01:07 PM Report #591135 Posted December 30, 2015 at 01:07 PM Bom dia, A primeira coisa que se me ocorre ao olhar para isso, é uma "maquina de estados". Creio que resolve o problema dos menus de forma simples. Cordiais cumprimentos, Apocsantos "A paciência é uma das coisas que se aprendeu na era do 48k" O respeito é como a escrita de código, uma vez perdido, dificilmente se retoma o habito"
HappyHippyHippo Posted December 30, 2015 at 01:19 PM Report #591136 Posted December 30, 2015 at 01:19 PM uma máquina de estados resolve estruturas de menus mais complexos, mas também torna a resolução mais complexa do que necessária o que estou a ver ao olhar para essa "árvore" não é mais do que chamadas de funções para entrar em submenus IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Edu123 Posted December 30, 2015 at 02:15 PM Author Report #591137 Posted December 30, 2015 at 02:15 PM Pois, e o que são máquinas de estados??? Só estou há dois meses nisto e ainda percebo muito pouco....
apocsantos Posted December 30, 2015 at 04:05 PM Report #591141 Posted December 30, 2015 at 04:05 PM Boa tarde, Vou deixar um exemplo, apenas por "brincadeira", mas não despensa que estudes. #include <stdio.h> #include <stdlib.h> #include <string.h> //carrega os headers readline e history, que fazem parte das biblitecas GNU Readline Library e se enconram na pasta readline //devem ser previamente instalados, no caso, usando GNU/Linux Ubunto, com o seguinte comando: // sudo apt-get install libreadline-dev #include <readline/readline.h> #include <readline/history.h> #include "main.h" // cria uma estrutura com o nome Estado, contendo o local em que o user se encontra. typedef enum { MAIN // principal ,CONT // conteudo ,ESCA // Opcao ,SAIR } estado; //Estrutura Comando, declara variável tipo estado, e apontadores do tipo caracter e função. typedef struct { estado es; char *cmd; void (*f)(char **,int); char *args; char *descricao; } comando; void dummy(char **,int); //função dummy recebe como argumentos um duplo apontador de caracteres, e um apontador de inteiro // função do tipo comando contendo os descritivos e chamando as funções respetivas a cada designação de comando. comando cmds[] = { {MAIN,"conteudo", troca_estado, "","Gerir conteudo"} ,{CONT,"adicionar", conteudo_adicionar, "","Cria um conteudo e adiciona na lista de conteudos"} ,{CONT,"listar", conteudo_listar, "","Mostra todos os conteudos disponiveis"} ,{CONT,"remover", conteudo_remover, "id","Remove permanentemente um determinado conteudo " "da lista de conteudos"} ,{CONT,"alterar", conteudo_alterar, "","Cria um conteudo e substitui um existente"} ,{CONT,"carregar", conteudo_carregar, "filename", "Carrega um conteudo de um ficheiro"} ,{CONT,"salvar", conteudo_salvar, "id filename", "Salva um conteudo para um ficheiro, se o ficheiro ja existir reescreve."} ,{CONT,"ajuda", imprime_ajuda, "","Mostra informacoes de ajuda para os comandos " "possiveis num determidado estado do programa"} ,{CONT,"sair", troca_estado, "","Volta ao menu principal"} ,{MAIN,"escalonamento", troca_estado, "","Gerir escalonamento"} ,{ESCA,"ajuda", imprime_ajuda, "","Mostra informacoes de ajuda para os comandos " "possiveis num determidado estado do programa"} ,{ESCA,"listar", esca_listar, "","Lista a programacao"} ,{ESCA,"l_utilizados",esca_l_utilizados,"","Lista os conteudos utilizados na programacao"} ,{ESCA,"sair", troca_estado, "","Volta ao menu principal"} ,{MAIN,"ajuda", imprime_ajuda, "","Mostra informacoes de ajuda para os comandos " "possiveis num determidado estado do programa"} ,{MAIN,"sair", troca_estado, "","Sair da aplicacao"} }; int nr_cmds; estado _es = MAIN; // Função SplashScreen , mostra etiqueta do trabalho void splashScreen() { printf("\x1b[32m"); printf("\x1b[1;5m"); printf("\x1b[0m"); } //funca dummy a er usada na maquina de estados do menu void dummy(char **words,int n) { int i; printf("Eu queria executar isto:\n"); for(i=0; i<n; i++) printf("%d/%d:%s\n",i,n,words[i]); } //funcao troca_estado, usada na maquina de estados, na transição entre estados, usados no menu void troca_estado(char **words, int n) { static short int ajuda_impressa[] = { 0,0}; //CONT,ESCA if(n>1) { printf("ERRO: Demasiados argumentos para comando %s.\n",words[0]); return; } switch (_es) { case MAIN: if(strcmp(words[0],"conteudo")==0) { _es = CONT; if(ajuda_impressa[0]==0) { imprime_ajuda(NULL,0); ajuda_impressa[0]=1; } } else if(strcmp(words[0],"escalonamento")==0) { _es = ESCA; if(ajuda_impressa[1]==0) { imprime_ajuda(NULL,0); ajuda_impressa[1]=1; } } else if(strcmp(words[0],"sair")==0) _es = SAIR; else printf("ERRO: Argumento inesperado ao trocar estado.\n"); break; case CONT: case ESCA: if(strcmp(words[0],"sair")==0) _es=MAIN; else printf("ERRO: Argumento inesperado ao trocar estado.\n"); break; case SAIR: printf("ERRO: Argumento inesperado ao trocar estado.\n"); } } //funcao imprime_ajuda, usada no menu, para exibir instruções de utilização void imprime_ajuda(char **words, int n) { int j; char buffer[1024]; if(n>1) { printf("Argumento(s) inesperado(s): %s.\n",words[1]); } printf("\x1b[33;1mComandos possiveis:\x1b[0m\n"); for(j=0; j<nr_cmds; j++) { if(_es == cmds[j].es) { sprintf(buffer,"%s %s",cmds[j].cmd,cmds[j].args); printf("\t\x1b[33m%-20s\x1b[0m: %s\n",buffer,cmds[j].descricao); } } } //funcao strip_line, usada para dividir linhas, quando o tamanho é excedido void strip_line(char *line, char **words, int *n) { char *ptr; char delim[] = " \t\r"; int i=0; ptr = strtok(line,delim); while(ptr!=NULL) { // words[i] = (char *)malloc( (strlen(ptr)+1)*sizeof(char)); // strcpy(words[i],ptr); words[i] = strdup(ptr); i++; ptr=strtok(NULL,delim); } *n=i; } //funcao strEstado, recebe como argumentos um estado char *strEstado(estado s) { static char *ss[] = { "" ," [conteudo]" ," [escalonamento]" }; switch(s) { case MAIN: case SAIR: return ss[0]; case CONT: return ss[1]; case ESCA: return ss[2]; } return ss[0]; } //funcao main int main(int argc, char *argv[]) { char *line; char prompt[1024]; nr_cmds = sizeof(cmds)/sizeof(cmds[0]); splashScreen(); imprime_ajuda(NULL,0); strcpy(prompt,"\x1b[44mGestor\x1b[0m >> "); while((line = readline(prompt))) { char *words[100]; int n=0; add_history(line); strip_line(line,words,&n); int i,run=0; for(i=0; i<nr_cmds; i++) { if(_es==cmds[i].es && strcmp(cmds[i].cmd,words[0])==0) { cmds[i].f(words,n); run=1; break; } } if(run==0) { printf("Comando desconhecido: %s.\n",words[0]); } // free words & line for(i=0; i<n; i++) free(words[i]); free(line); // reset prompt sprintf(prompt,"\x1b[44mGestor%s\x1b[0m >> ",strEstado(_es)); } return 0; } Este código é antigo e foi feito para um projecto académico, faz mais de 2 anos... Espero que te dê para teres umas luzes de uma das soluções. De qualquer das formas estou de acordo com o HHH, podes fazer isto de forma bem mais simples. Cordiais cumprimentos, Apocsantos "A paciência é uma das coisas que se aprendeu na era do 48k" O respeito é como a escrita de código, uma vez perdido, dificilmente se retoma o habito"
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