Jump to content

Menu de opções


Ana Silva

Recommended Posts

Ana Silva

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;
  }

 

Link to post
Share on other sites
@Andre Filipe

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 by @Andre Filipe
Link to post
Share on other sites
thoga31

Há alguns pontos a ter em conta na resolução deste problema antes mesmo do menu:

  1. Qual a estrutura de dados para guardar informações acerca de um animal?
  2. Qual a estrutura de dados para guardar informações acerca de vários animais?
  3. 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:

  1. Variáveis globais;
  2. 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!

Link to post
Share on other sites
Ana Silva
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! :D

Link to post
Share on other sites
Ana Silva
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:

  1. Qual a estrutura de dados para guardar informações acerca de um animal?
  2. Qual a estrutura de dados para guardar informações acerca de vários animais?
  3. 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:

  1. Variáveis globais;
  2. 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!! :D

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!

Link to post
Share on other sites
thoga31
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!

Link to post
Share on other sites
Ana Silva
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

Link to post
Share on other sites
thoga31
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!

Link to post
Share on other sites
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

Link to post
Share on other sites

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!

Link to post
Share on other sites

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.