Ana Silva Posted January 2, 2021 at 05:35 PM Report #620866 Posted January 2, 2021 at 05:35 PM Boas pessoal! Eu tenho de fazer um menu de opções sobre animais ao qual algumas das categorias são: 1- Inserir animal 2- Consultar animal 3- Alterar animal 3- Adicionar os seus gastos O código que eu tenho para ja é so do inicio mas nao sei como faço para o utilizador poder adicionar um animal e este animal ser guardado na memoria a fim de se utilizar mais tarde Depois de inserir o animal gostaria que voltasse ao menu inicial Poderiam me ajudar? Sou nova na programação O meu codigo ate agora: void InserirAnimal(void){ printf("Insira o animal:"); } #include <stdio.h> int main() { char opcao; char animal; do{ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("v Menu inicial: v\n"); printf("v O que pretende fazer? v\n"); printf("v 1- Inserir animal v\n"); printf("v 2- Consultar animais existentes v\n"); printf("v 3- Alterar nome de animal v\n"); printf("v 4- Inserir despesas dos animais v\n"); printf("v 5- Sair do programa v\n"); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("Opcao:"); scanf("%c", &opcao); fflush(stdin); //para nao assumir duas opcoes: a opcao escolhida e a 'invalida' switch(opcao){ case '1': printf("Opcao 1 selecionada\n"); InserirAnimal(); scanf("%c",&animal);break; case '2': printf("Opcao 2 selecionada\n");break; case '3': printf("Opcao 3 selecionada\n");break; case '4': printf("Opcao 4 selecionada\n");break; case '5': printf("Opcao 5 selecionada\n");break; default: printf("Opcao invalida\n");break; } } while (opcao != '5'); return 0; }
@Andre Filipe Posted January 2, 2021 at 08:53 PM Report #620867 Posted January 2, 2021 at 08:53 PM (edited) Desculpa não consigo fazer isso em C, mas consigo fazer em Python. Se quiseres que te faça um menu desses em python eu faço. Queres que eu faça em Python? Edited January 2, 2021 at 08:53 PM by @Andre Filipe I never give up!
thoga31 Posted January 2, 2021 at 10:01 PM Report #620868 Posted January 2, 2021 at 10:01 PM Há alguns pontos a ter em conta na resolução deste problema antes mesmo do menu: Qual a estrutura de dados para guardar informações acerca de um animal? Qual a estrutura de dados para guardar informações acerca de vários animais? Onde guardar essa estrutura de dados em memória para que o programa todo lhe possa aceder? Para guardar informações acerca de um animal, recomendo de caras o uso de uma struct. Desta forma podes guardar diferentes informações acerca de um animal numa estrutura que lhe é dedicada. typedef struct { char nome[64]; char genero; int idade; // outras informações... } ANIMAL; De seguida, a estrutura clara para guardar vários animais é um vector. Como és nova em programação, decerto não estarás familizarizada com o conceito de memória dinâmica e a sua respectiva alocação. Irei, portanto, sugerir a opção clássica de vectores estáticos (i.e. com um tamanho bem definido). #define DIM 128 ANIMAL animais[DIM]; Contudo, vou aqui introduzir um pequeno "truque" para manter registo do que se passa nesse vector. Uma vez que um vector estático tem n elementos em memória, estejam eles preenchidos com dados ou não, é boa ideia manter um inteiro para registar quantos elementos do vector estão de facto ocupados. #define DIM 128 // dimensão do vector ANIMAL animais[DIM]; // vector de animais int quantos; // quantos animais estão guardados Faço notar, contudo, que este "truque" é meramente opcional e existem outras formas de abordar a gestão do vector. Por fim, há duas formas principais de registar os dados de tal forma que todo o programa lhe tenha acesso: Variáveis globais; Variáveis locais (com passagem por parâmetro a funções). A minha opção favorita costuma ser a segunda, apesar de já ter encontrado situações em que variáveis globais se revelaram imprescindíveis. Há vários argumentos para esta minha preferência, mas não sendo objecto do teu problema, passarei esse debate em frente. Considera então este exemplo de um programa que usa uma variável local: #include <stdio.h> int ler(void) { int x; scanf("%d", &x); return x; } void escrever(int x) { printf("%d\n", x); } int main(void) { int n; n = ler(); escrever(n); return 0; } Neste caso, o inteiro n está presente na função main, mas não é visível fora dela! Tens de ter mecanismos de passar o seu valor entre funções. Neste caso em particular, a função ler() lê um inteiro e devolve-o, podendo ser posteriormente armazenado em qualquer variável inteira. Isto torna a função reutilizável. O mesmo acontece com a função escrever(): ela recebe um inteiro, qualquer que ele seja, e faz output dele. Passemos então ao teu programa. Podemos criar funções para cada uma das opções associadas ao menu e assim chamá-las com um switch, conforme começaste por fazer no teu código. Enquanto o vector de animais é guardado no domínio da função main(), as outras funções têm de receber ou enviar os dados necessários. Esta é, portanto, uma comunicação entre funções. Por exemplo, a função que lê um animal vai ler os dados de um animal e enviá-lo sob a forma de uma estrutura ANIMAL à função main() para que esta o guarde no seu vector. Por seu turno, a função que mostra os animais vai receber o vector e quantos animais estão registados, sendo estas informações enviadas pela main() através dos argumentos da função que escreve os dados. Isto deverá traduzir-se em algo como o seguinte: #include <stdio.h> #define OPCAO_SAIR 0 #define LIM_NOME 64 #define DIM 128 typedef struct { char nome[LIM_NOME]; char genero; int idade; } ANIMAL; ANIMAL lerAnimal(void) { ANIMAL bichano; // ler dados do bichano return bichano; } void mostrarAnimais(ANIMAL animais[], int n) { for (int i = 0; i < n; i++) { // mostrar informações sobre o animal no índice i } } int main(void) { ANIMAL animais[DIM]; int quantos = 0; int opcao; do { // mostrar opções scanf("%d", &opcao); switch (opcao) { case 0: break; case 1: if (quantos < DIM) { animais[quantos] = lerAnimal(); quantos++; } else { printf("Falta espaço, meu caro :(\n"); } break; case 2: mostrarAnimais(animais, quantos); break; // outros casos... default: printf("Desconheço tal opção!\n"); } } while (opcao != OPCAO_SAIR); return 0; } Enquanto não seleccionares a opção 0 (zero), o programa continua a mostrar o menu após cada operação, mantendo registado em memória as alterações que fizeres ao vector de animais desde que o passes correctamente por argumento às funções que criares, quando necessário. Cumprimentos. Knowledge is free!
Ana Silva Posted January 7, 2021 at 10:43 AM Author Report #620908 Posted January 7, 2021 at 10:43 AM Em 02/01/2021 às 20:53, @Andre Filipe disse: Desculpa não consigo fazer isso em C, mas consigo fazer em Python. Se quiseres que te faça um menu desses em python eu faço. Queres que eu faça em Python? Precisava mesmo que fosse em C mas obrigada pela ajuda na mesma! 😄
Ana Silva Posted January 7, 2021 at 10:47 AM Author Report #620909 Posted January 7, 2021 at 10:47 AM Em 02/01/2021 às 22:01, thoga31 disse: Há alguns pontos a ter em conta na resolução deste problema antes mesmo do menu: Qual a estrutura de dados para guardar informações acerca de um animal? Qual a estrutura de dados para guardar informações acerca de vários animais? Onde guardar essa estrutura de dados em memória para que o programa todo lhe possa aceder? Para guardar informações acerca de um animal, recomendo de caras o uso de uma struct. Desta forma podes guardar diferentes informações acerca de um animal numa estrutura que lhe é dedicada. typedef struct { char nome[64]; char genero; int idade; // outras informações... } ANIMAL; De seguida, a estrutura clara para guardar vários animais é um vector. Como és nova em programação, decerto não estarás familizarizada com o conceito de memória dinâmica e a sua respectiva alocação. Irei, portanto, sugerir a opção clássica de vectores estáticos (i.e. com um tamanho bem definido). #define DIM 128 ANIMAL animais[DIM]; Contudo, vou aqui introduzir um pequeno "truque" para manter registo do que se passa nesse vector. Uma vez que um vector estático tem n elementos em memória, estejam eles preenchidos com dados ou não, é boa ideia manter um inteiro para registar quantos elementos do vector estão de facto ocupados. #define DIM 128 // dimensão do vector ANIMAL animais[DIM]; // vector de animais int quantos; // quantos animais estão guardados Faço notar, contudo, que este "truque" é meramente opcional e existem outras formas de abordar a gestão do vector. Por fim, há duas formas principais de registar os dados de tal forma que todo o programa lhe tenha acesso: Variáveis globais; Variáveis locais (com passagem por parâmetro a funções). A minha opção favorita costuma ser a segunda, apesar de já ter encontrado situações em que variáveis globais se revelaram imprescindíveis. Há vários argumentos para esta minha preferência, mas não sendo objecto do teu problema, passarei esse debate em frente. Considera então este exemplo de um programa que usa uma variável local: #include <stdio.h> int ler(void) { int x; scanf("%d", &x); return x; } void escrever(int x) { printf("%d\n", x); } int main(void) { int n; n = ler(); escrever(n); return 0; } Neste caso, o inteiro n está presente na função main, mas não é visível fora dela! Tens de ter mecanismos de passar o seu valor entre funções. Neste caso em particular, a função ler() lê um inteiro e devolve-o, podendo ser posteriormente armazenado em qualquer variável inteira. Isto torna a função reutilizável. O mesmo acontece com a função escrever(): ela recebe um inteiro, qualquer que ele seja, e faz output dele. Passemos então ao teu programa. Podemos criar funções para cada uma das opções associadas ao menu e assim chamá-las com um switch, conforme começaste por fazer no teu código. Enquanto o vector de animais é guardado no domínio da função main(), as outras funções têm de receber ou enviar os dados necessários. Esta é, portanto, uma comunicação entre funções. Por exemplo, a função que lê um animal vai ler os dados de um animal e enviá-lo sob a forma de uma estrutura ANIMAL à função main() para que esta o guarde no seu vector. Por seu turno, a função que mostra os animais vai receber o vector e quantos animais estão registados, sendo estas informações enviadas pela main() através dos argumentos da função que escreve os dados. Isto deverá traduzir-se em algo como o seguinte: #include <stdio.h> #define OPCAO_SAIR 0 #define LIM_NOME 64 #define DIM 128 typedef struct { char nome[LIM_NOME]; char genero; int idade; } ANIMAL; ANIMAL lerAnimal(void) { ANIMAL bichano; // ler dados do bichano return bichano; } void mostrarAnimais(ANIMAL animais[], int n) { for (int i = 0; i < n; i++) { // mostrar informações sobre o animal no índice i } } int main(void) { ANIMAL animais[DIM]; int quantos = 0; int opcao; do { // mostrar opções scanf("%d", &opcao); switch (opcao) { case 0: break; case 1: if (quantos < DIM) { animais[quantos] = lerAnimal(); quantos++; } else { printf("Falta espaço, meu caro :(\n"); } break; case 2: mostrarAnimais(animais, quantos); break; // outros casos... default: printf("Desconheço tal opção!\n"); } } while (opcao != OPCAO_SAIR); return 0; } Enquanto não seleccionares a opção 0 (zero), o programa continua a mostrar o menu após cada operação, mantendo registado em memória as alterações que fizeres ao vector de animais desde que o passes correctamente por argumento às funções que criares, quando necessário. Cumprimentos. Muito obrigada a serio!! 😄 Em relação ao inicio do struct eu não dei esse ''comando'' assim dizendo daria para substituir por outro? Mais uma vez obrigada tentarei fazer de novo o código com sua ajuda!
thoga31 Posted January 7, 2021 at 08:43 PM Report #620917 Posted January 7, 2021 at 08:43 PM 9 horas atrás, Ana Silva disse: Em relação ao inicio do struct eu não dei esse ''comando'' assim dizendo daria para substituir por outro? Referes-te ao typedef? Esta palavra reservada do C permite definir novos tipos de dados. Neste caso, a seguinte estrutura... struct { char nome[LIM_NOME]; char genero; int idade; } ... vai passar a ser conhecida como o tipo de dados ANIMAL. Contudo, podes definir a estrutura sem o typedef: struct Animal { char nome[LIM_NOME]; char genero; int idade; } A desvantagem é teres de te referir a ela sempre como struct Animal em vez de apenas ANIMAL: # Usando typedef, declaras assim uma variável: ANIMAL bichano; # Sem o typedef, dclaras assim: struct Animal bichano; Cumprimentos. Knowledge is free!
Ana Silva Posted January 8, 2021 at 12:33 PM Author Report #620924 Posted January 8, 2021 at 12:33 PM 15 horas atrás, thoga31 disse: Referes-te ao typedef? Esta palavra reservada do C permite definir novos tipos de dados. Neste caso, a seguinte estrutura... struct { char nome[LIM_NOME]; char genero; int idade; } ... vai passar a ser conhecida como o tipo de dados ANIMAL. Contudo, podes definir a estrutura sem o typedef: struct Animal { char nome[LIM_NOME]; char genero; int idade; } A desvantagem é teres de te referir a ela sempre como struct Animal em vez de apenas ANIMAL: # Usando typedef, declaras assim uma variável: ANIMAL bichano; # Sem o typedef, dclaras assim: struct Animal bichano; Cumprimentos. Obrigadaaa! Em relação a alterar o nome do animal como aconcelhas que faça já com os dados introuduzidos lá? Estava a pensar em escrever os mesmos dados em ficheiros mas não sei se há uma opção mais simples
thoga31 Posted January 10, 2021 at 12:06 AM Report #620936 Posted January 10, 2021 at 12:06 AM Em 08/01/2021 às 12:33, Ana Silva disse: Em relação a alterar o nome do animal como aconcelhas que faça já com os dados introuduzidos lá? Em termos de variável, podes alterar a qualquer momento. Tem em atenção que, no caso de strings, deves usar a função strcpy(). Para guardar no ficheiro, a opção mais simples pode ser reescrever o ficheiro apenas ao sair do programa por opção no menu. Ou seja, quando o utilizador pede para sair, tratas de escrever de novo o ficheiro em disco com os novos dados do vector. Knowledge is free!
Ana Silva Posted January 15, 2021 at 12:41 PM Author Report #620974 Posted January 15, 2021 at 12:41 PM Em 10/01/2021 às 00:06, thoga31 disse: Em termos de variável, podes alterar a qualquer momento. Tem em atenção que, no caso de strings, deves usar a função strcpy(). Para guardar no ficheiro, a opção mais simples pode ser reescrever o ficheiro apenas ao sair do programa por opção no menu. Ou seja, quando o utilizador pede para sair, tratas de escrever de novo o ficheiro em disco com os novos dados do vector. Vou usar o strcpy, sabe me dizer como posso alterar apenas uma categoria do meio com essa função? Exemplo de animais: 1- panda 2-macaco 3-koala Se eu quiser alterar o nome do animal 2 para gato como faço ? Obrigada
thoga31 Posted January 15, 2021 at 08:32 PM Report #620980 Posted January 15, 2021 at 08:32 PM Tens de ir à posição no vetor que contém o animal "macaco" e alterar o campo correspondente (vamos assumir neste caso que é nome). // Estando o "macaco" guardado no índice i: strcpy(bichanos[i].nome, "gato"); Cumprimentos. Knowledge is free!
Ana Silva Posted January 23, 2021 at 09:17 PM Author Report #621054 Posted January 23, 2021 at 09:17 PM (edited) Em 15/01/2021 às 20:32, thoga31 disse: Tens de ir à posição no vetor que contém o animal "macaco" e alterar o campo correspondente (vamos assumir neste caso que é nome). // Estando o "macaco" guardado no índice i: strcpy(bichanos[i].nome, "gato"); Cumprimentos. Isso como código e assumindo que o utilizador que escolhe o animal podemos fazer? Do genero: char nome[20]; int i = 0; print("Qual animal deseja alterar?") scanf("%s",nome) strcpy(bichanos[i] .nome, "%s"); Edited January 23, 2021 at 09:21 PM by thoga31 GeSHi
thoga31 Posted January 23, 2021 at 09:23 PM Report #621056 Posted January 23, 2021 at 09:23 PM Esse código não procura pelo animal que queres alterar. O que faz é alterar o nome do animal guardado no índice i para o nome que leres do teclado. Tens de saber previamente qual é esse índice i com uma função de pesquisa. Knowledge is free!
Ana Silva Posted January 23, 2021 at 09:28 PM Author Report #621057 Posted January 23, 2021 at 09:28 PM 4 minutos atrás, thoga31 disse: Esse código não procura pelo animal que queres alterar. O que faz é alterar o nome do animal guardado no índice i para o nome que leres do teclado. Tens de saber previamente qual é esse índice i com uma função de pesquisa. entao talvez usar um for para acompanhar o i?
thoga31 Posted January 24, 2021 at 02:12 AM Report #621059 Posted January 24, 2021 at 02:12 AM (edited) Sim, por exemplo: // Função de procura int procurar(ANIMAL *bichos, int n, const char *nome) { for(int i = 0; i < n; i++) { if (strcmp(bichos[i].nome, nome) == 0) return i; } return -1; } // Como usar: int pos = procurar(bichanos, quantos, "macaco"); if (pos >= 0) { strcpy(bichanos[pos].nome, "gato"); } Cumprimentos. Edited January 25, 2021 at 06:27 AM by thoga31 Correcção do código Knowledge is free!
Ana Silva Posted January 25, 2021 at 04:49 PM Author Report #621065 Posted January 25, 2021 at 04:49 PM (edited) Em 24/01/2021 às 02:12, thoga31 disse: Sim, por exemplo: // Função de procura int procurar(ANIMAL *bichos, int n, const char *nome) { for(int i = 0; i < n; i++) { if (strcmp(bichos[i].nome, nome) == 0) return i; } return -1; } // Como usar: int pos = procurar(bichanos, quantos, "macaco"); if (pos >= 0) { strcpy(bichanos[pos].nome, "gato"); } Cumprimentos. void alterarAnimal(){ printf("Qual animal deseja alterar?"); scanf("%d",&n_animais); printf("Para qual categoria deseja alterar?"); scanf("%s",nome); printf("Animais:\n"); for(int n = 1; n<=n_animais; n++){ for(int i = 0; i<n_animais; i++){ printf("%d:",n); n++; strcpy(animal[i], nome); printf("%s\n", animal[i]); } }} Eu fiz desse jeito mas não está dando certo poderiam verificar o erro? Edited January 25, 2021 at 07:47 PM by thoga31 GeSHi
thoga31 Posted January 25, 2021 at 08:07 PM Report #621066 Posted January 25, 2021 at 08:07 PM Não entendi qual é a tua ideia com esse código. Se estás a pedir ao utilizador o número do animal a ser modificado (scanf("%d",&n_animais);), por que motivo estás a percorrer a lista com dois ciclos for, a incrementar o n por duas vezes e a copiar o novo nome em todos os índices de 0 até ao número lido? Ou estás a tentar mostrar os animais todos depois de (supostamente) alterar o nome? O código que te dei funciona perfeitamente bem para procurar o índice na lista de um animal com um dado nome. Encontrado esse índice, é só alterar o nome nesse índice, mais nada. void alterarAnimal(void) { char nome[64]; // String para guardar os nomes dados pelo utilizador printf("Nome do animal a alterar? "); // Primeiro lemos o nome do animal a ser alterado fgets(nome, 64, stdin); int pos = procurar(bichanos, quantos, nome); // Procuramos o índice do vector que contém o animal com o nome dado if (pos >= 0) { /* O animal está registado no vector */ printf("Novo nome do animal? "); // Lemos o novo nome do animal fgets(nome, 64, stdin); strcpy(bichanos[pos].nome, nome); // Copiamos o novo nome para o campo "nome" do animal no índice "pos" } else { /* O animal NÃO foi encontrado (pos = -1), logo não existe no vector */ printf("Não existe um animal com nome %s.\n", nome); } } Por outro lado, se de facto queres que o utilizador te diga o índice na lista e não o nome original do animal a alterar, então basta isto: void alterarAnimal(void) { printf("Qual animal deseja alterar?"); scanf("%d", &i); printf("Para qual categoria deseja alterar?"); scanf("%s", nome); strcpy(animal[i], nome); } Adicionalmente, recomendo mostrar o conteúdo do vector com recurso uma função que possas chamar sempre que precisares: void listarAnimais(ANIMAL *bichos, int n) { printf("Existem %d animais registados.", n); for (int i = 0; i < n; i++) { printf("Registo %d:\n", i); printf("Nome: %s\n" , bichos[i].nome); printf("Genero: %c\n" , bichos[i].genero); printf("Idade: %d\n" , bichos[i].idade); } } Cumprimentos. Knowledge is free!
Ana Silva Posted January 26, 2021 at 04:40 PM Author Report #621077 Posted January 26, 2021 at 04:40 PM 20 horas atrás, thoga31 disse: Não entendi qual é a tua ideia com esse código. Se estás a pedir ao utilizador o número do animal a ser modificado (scanf("%d",&n_animais);), por que motivo estás a percorrer a lista com dois ciclos for, a incrementar o n por duas vezes e a copiar o novo nome em todos os índices de 0 até ao número lido? Ou estás a tentar mostrar os animais todos depois de (supostamente) alterar o nome? O código que te dei funciona perfeitamente bem para procurar o índice na lista de um animal com um dado nome. Encontrado esse índice, é só alterar o nome nesse índice, mais nada. void alterarAnimal(void) { char nome[64]; // String para guardar os nomes dados pelo utilizador printf("Nome do animal a alterar? "); // Primeiro lemos o nome do animal a ser alterado fgets(nome, 64, stdin); int pos = procurar(bichanos, quantos, nome); // Procuramos o índice do vector que contém o animal com o nome dado if (pos >= 0) { /* O animal está registado no vector */ printf("Novo nome do animal? "); // Lemos o novo nome do animal fgets(nome, 64, stdin); strcpy(bichanos[pos].nome, nome); // Copiamos o novo nome para o campo "nome" do animal no índice "pos" } else { /* O animal NÃO foi encontrado (pos = -1), logo não existe no vector */ printf("Não existe um animal com nome %s.\n", nome); } } Por outro lado, se de facto queres que o utilizador te diga o índice na lista e não o nome original do animal a alterar, então basta isto: void alterarAnimal(void) { printf("Qual animal deseja alterar?"); scanf("%d", &i); printf("Para qual categoria deseja alterar?"); scanf("%s", nome); strcpy(animal[i], nome); } Adicionalmente, recomendo mostrar o conteúdo do vector com recurso uma função que possas chamar sempre que precisares: void listarAnimais(ANIMAL *bichos, int n) { printf("Existem %d animais registados.", n); for (int i = 0; i < n; i++) { printf("Registo %d:\n", i); printf("Nome: %s\n" , bichos[i].nome); printf("Genero: %c\n" , bichos[i].genero); printf("Idade: %d\n" , bichos[i].idade); } } Cumprimentos. Muito obrigada aserio já consegui por a funcionar essa parte vou avançar para a proxima!
Ana Silva Posted February 1, 2021 at 04:54 PM Author Report #621144 Posted February 1, 2021 at 04:54 PM Boas! Pessoal agora para fazer a parte de inserir despesas de cada animal sugerem-me usar vetores de memoria ou ficheiros? Eu em cada despesa tenho de colocar a data, categoria e o valor
thoga31 Posted February 1, 2021 at 05:02 PM Report #621145 Posted February 1, 2021 at 05:02 PM 6 minutos atrás, Ana Silva disse: sugerem-me usar vetores de memoria ou ficheiros? A verdadeira questão é outra: queres guardar os dados entre cada execução do programa? Se queres abrir o programa e manter os dados da sessão anterior, tens de usar ficheiros. Contudo, se isso não for preciso, basta um vetor tal como tens feito até ao momento. Cumprimentos. Knowledge is free!
Ana Silva Posted February 1, 2021 at 10:55 PM Author Report #621148 Posted February 1, 2021 at 10:55 PM 5 horas atrás, thoga31 disse: A verdadeira questão é outra: queres guardar os dados entre cada execução do programa? Se queres abrir o programa e manter os dados da sessão anterior, tens de usar ficheiros. Contudo, se isso não for preciso, basta um vetor tal como tens feito até ao momento. Cumprimentos. Eu queria guardar quando colocasse os dados os antigos são apagados assim como os animais são introduzidos sempre que entrar. Aí como faço em memoria (da mesma forma que os animais)?
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