Ir ao conteúdo
  • Cadastre-se

C Programa de banco de dados com struct em C


ningumx
Ir à solução Resolvido por arfneto,

Posts recomendados

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


typedef struct aluno {
	int id_aluno;
	char nm_aluno[50];
	int delete;
	int ativo;
} Aluno;

Aluno alunos[10];
  
//FUNÇÃO MENU PRINCIPAL
void menu();

//Funções ALUNO
void aluno();
void cadastro_aluno();
void consulta_id();
void exclui_id();
void altera_id();
void relatorio();

//Funções NOTA
void notas();
void inclui_nota();
void altera_nota();
void exclui_nota();
void consulta_nota();

int main(){
	menu();
	aluno();
	notas();
	relatorios();
	return 0;
}




//-------------FUNÇÕES MENU--------------

void menu(){
	int opcao1;
    while(opcao1 != 4){
        system("cls");
    	printf("\t\t\t=====MENU=====");
	    printf("\n\n\n\t\t\t\t     1. Aluno\n");
	    printf("\t\t\t\t     2. Notas\n");
	    printf("\t\t\t\t     3. Relatório\n");
	    printf("\t\t\t\t     4. Sair\n");
	    printf("\t\t\t\t    _____________________\n");
	    printf("\t\t\t\t     ");
	    scanf("%d", &opcao1);
	    getchar();
	

		switch (opcao1){
			case 1:
				aluno();
				break;
			case 2:
				notas();
				break;
			case 3:
				relatorios();
				break;
			case 4:
				printf("\n\t\t\t\tVolte sempre.\n\n");
	          	exit(0);
	        	break;
			default:
				printf("\n\t\t\t\t\tEscreva um número válido.\n\n");
				break;
		}
	}
}

void cadastro_aluno(Aluno){
	system("cls");
	printf("\t\t\t\t=======Cadastro do Aluno=======\n\n\n"); 
    
	for(int i = 0 ; i < 10 ; i++) {
		for(int j = 0 ; j < 10 ; j++){
		    printf("Cógido do aluno: ");
		    scanf("%d", &aluno[i].id_aluno[j]);
		}

	    printf("Digite o nome do aluno: ");
	    scanf("%s%*c", &aluno[i].nm_aluno);

	    //Analisar se o aluno está ativo
	    for(int k = 0 ; k < 10 < i++){
	    	if(alunos[k].ativo == 0){
	    		strcpy(alunos[k].id_aluno, id_aluno);
	    		alunos[k].ativo = 1;
	    		break;
	    	}
	    }

	    //Nome maior que 3 caracteres
	    if(strlen(aluno[i].nm_aluno) < 3){
	    	printf("Digite o nome do aluno: ");

	    printf(" \n ------------------------------------------------------------------------\n");
	    }
	}
}

void consulta_id(Aluno){
	system("cls");
	printf(" \n Digite um código: ");
	scanf("%d", &cod);
	 
	for(i = 0 ; i < 10 ; i++) {
	    if(strcmp(cod, aluno[i].id_aluno)== 0) {
	        printf("\n Registro encontrado! ");
	        posicao = i;
	    } else {
	        posicao = -1;
	    }
	}

Estou fazendo um programa que faz um cadastro de 10 alunos, 3 notas cada. A questão é que estou meio confusa com os structs e já na primeira função "aluno" dá erro. Alguém poderia dizer como posso melhorar? (Essa é apenas uma parte do código). Valeu!

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Seu programa não está nada bom ainda.

 

O maior problema está nos dados, na composição dos dados. Ou na total falta dela.

Mas tem muitos dos problemas comuns dos programas de iniciantes que são publicados aqui. Eu tenho uma lista para poder copiar e colar os itens. 😞 e acho que é um sinal do modo como ensinam essas coisas hoje em dia.

 

De volta ao programa

 


typedef struct aluno {
	int id_aluno;
	char nm_aluno[50];
	int delete;
	int ativo;
} Aluno;

Aluno alunos[10];
  
//FUNÇÃO MENU PRINCIPAL
void menu();

//Funções ALUNO
void aluno();
void cadastro_aluno();
void consulta_id();
void exclui_id();
void altera_id();
void relatorio();

//Funções NOTA
void notas();
void inclui_nota();
void altera_nota();
void exclui_nota();
void consulta_nota();

 

Nessas primeiras linhas já dá pra ver que vai demorar muito mais do que precisa pra concluir isso. E não vai ficar bom. E vai levar pouco ou nada desse programa para o próximo.

 

  • NUNCA use funções void e sem argumentos. De pouco ou nada vão servir. Só vão funcionar uma vez para um certo dado. Ninguém faria um programa para rodar uma vez só com um dado só se fosse ensinado corretamente.
  • uma função menu() retorna a opção. E não faz mais nada. Não tem sentido colocar lógica do programa dentro de uma função menu().
  • Use coment;arios em seu programa. Comente o que está fazendo e porque está fazendo. Mas não comente  coisas pouco irrelevantes como "funções nota" , "variávies",  "protótipos" ... é o óbvio.
  • Seu programa fala de um banco de dados. Mas onde está ele?????? Escreva em torno dos dados.
  • NUNCA use nada global
  • scanf() retorna um int. SEMPRE teste. É ingênuo seguir sem ler.

 

typedef struct aluno {
	int id_aluno;
	char nm_aluno[50];
	int delete;
	int ativo;
} Aluno;

Aluno alunos[10];

 

  • Precisa de DOIS int para controlar delete/ativo? 64 bits ao invés de 1 ou 2?
  • E aluno[10] parece um banco de dados? O unico? E quantos dados tem? Global? 
  • Todos esses campos se referem a aluno, estão DENTRO da estrutura. Para que ficar repetindo aluno??
  • Não há ponteiros dentro da estrutura então para que dois nomes aluno e Aluno???
  • Onde estão as notas dos alunos?
  • Onde está relatorio()?

    Compare:
#define LIMITE_ 10
  
typedef struct 
{
    int  id;
    char nome[50];
    char status;
} Aluno;

typedef struct
{
    int      id;
    char     nome[50];
    unsigned limite;        // quantos cabem
    unsigned qtd;           // quantos tem
    Aluno    aln[LIMITE_];  // os alunos
} Turma;

 

Isso faria sua vida MUITO mais simples. Um Aluno é um aluno. Uma Turma tem alunos e cada turma tem um nome, sua capacidade e seu totalizador. Essa é a noção de encapsulamento.

 

E a funções?

 

Considere coisas  como

 


char menu();

int  cadastrar(Aluno* A, Turma* T);
int  alterar(int id, Turma* T, Aluno* A);
int  consultar(int id, Turma* T);
int  excluir(int id, Turma* T);

 

claro, menu() retorna a opção. Não faz mais nada.

 

cadastrar() cadastra um aluno em uma turma, o simples. e retorna um status.

consultar() recebe um id e retorna um status negativo ou a posição na Turma, id.

alterar altera o aluo com um certo id e troca pelo registro A que foi passado.

 

O simples. Assim já pode escrever e testar as funções sem depender de dados externos.

 

 

E o programa sequer compila porque tem muitos erros e está incompleto

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Com certeza, preciso mudar tudo.

Vamos lá.

Defini uma struct para o código e o nome dos 10 alunos e outra para colocar 3 notas de cada aluno:

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


typedef struct Aluno {
	int id_aluno;
	char nm_aluno[50];
	int delete;
	int ativo;
} Aluno;


typedef struct notas {
	int id_aluno;
	int id_nota;
	float vl_nota;
} Notas;

 

Declarei uma série de funções pois terá mais de um menu, então preferi separar cada coisa: 

Obs: Preciso mudar o "void" ainda.

//FUNÇÃO MENU PRINCIPAL
void menu();

//Funções ALUNO
void aluno();
void cadastro_aluno();
void consulta_id();
void exclui_id();
void altera_id();
void relatorio();

//Funções NOTA
void notas();
void inclui_nota();
void altera_nota();
void exclui_nota();
void consulta_nota();

//Funções RELATÓRIO
void relatorios();
void rel_notas();
void rel_medias();

 

Na "main" coloquei os menus que o programa irá ter. 

Dentro de cada menu coloquei as funções.

int main(){
	menu();
	aluno();
	notas();
	relatorios();
	return 0;
}




//-------------FUNÇÕES MENU--------------

//menu principal para acessar os outros menus
void menu(){
	int opcao1;
    while(opcao1 != 4){
        system("cls");
    	printf("\t\t\t=====MENU=====");
	    printf("\n\n\n\t\t\t\t     1. Aluno\n");
	    printf("\t\t\t\t     2. Notas\n");
	    printf("\t\t\t\t     3. Relatório\n");
	    printf("\t\t\t\t     4. Sair\n");
	    printf("\t\t\t\t    _____________________\n");
	    printf("\t\t\t\t     ");
	    scanf("%d", &opcao1);
	    getchar();
	

		switch (opcao1){
			case 1:
				aluno();
				break;
			case 2:
				notas();
				break;
			case 3:
				relatorios();
				break;
			case 4:
				printf("\n\t\t\t\tVolte sempre.\n\n");
	          	exit(0);
	        	break;
			default:
				printf("\n\t\t\t\t\tEscreva um número válido.\n\n");
				break;
		}
	}
}



void aluno(){
	int opcao;
    do
    {
    	system("cls");
        printf(" \n=====MENU ALUNO===== ");
        printf(" \n1. Cadastrar");
        printf(" \n2. Consultar por ID");
        printf(" \n3. Excluir por ID");
        printf(" \n4. Alterar por ID");
        printf(" \n5. Relatório");
        printf(" \n6. Voltar");
        scanf("%d", &opcao);

        switch(opcao)
        {
            case 1:
                cadastro_aluno();
            	break;
            case 2:
                consulta_id();
            	break;
            case 3:
                exclui_id();
            	break;   
        	case 4:
        		altera_id();
        		break;
        	case 5:
        		relatorio();
        		break;
        	case 6:
        		menu();
        		break;
            default:
            	printf("Digite um número válido!");
            	break;
        }
    }
    while(opcao != 0);
}


void notas(){
	int opcao;
    do
    {
    	system("cls");
        printf(" \n=====MENU NOTAS===== ");
        printf(" \n1. Incluir nota do aluno");
        printf(" \n2. Alterar nota do aluno");
        printf(" \n3. Excluir nota do aluno");
        printf(" \n4. Consultar notas do aluno");
        printf(" \n5. Voltar");
        scanf("%d", &opcao);
        switch(opcao)
        {
            case 1:
                inclui_nota();
            	break;
            case 2:
                altera_nota();
            	break;
            case 3:
                exclui_nota();
            	break;   
        	case 4:
        		consulta_nota();
        		break;
        	case 5:
        		menu();
        		break;
            default:
            	printf("Digite um número válido!");
            	break;
        }
    }
    while(opcao != 0);
}



void relatorios(){
	int opcao;
    do
    {
    	system("cls");
        printf(" \n=====MENU RELATÓRIOS===== ");
        printf(" \n1. Relatório de notas");
        printf(" \n2. Relatório de médias");
        printf(" \n3. Voltar");
        scanf("%d", &opcao);
        switch(opcao)
        {
            case 1:
                rel_notas();
            	break;
            case 2:
                rel_medias();
            	break;
        	case 3:
        		menu();
        		break;
            default:
            	printf("Digite um número válido!");
            	break;
        }
    }
    while(opcao != 0);
}

 

Após isso, estou fazendo as funções para cada coisa. Porém estou bem confusa no funcionamento do struct no meu programa.

 

void cadastro_aluno(Aluno){
	system("cls");
	printf("\t\t\t\t=======Cadastro do Aluno=======\n\n\n"); 
    
	for(int i = 0 ; i < 10 ; i++) {
		for(int j = 0 ; j < 10 ; j++){
		    printf("Cógido do aluno: ");
		    scanf("%d", &aluno[i].id_aluno[j]);
		}

	    printf("Digite o nome do aluno: ");
	    fgets(aluno[i].nm_aluno, 50, stdin);
	}    

	//Analisar se o aluno está ativo
	for(int k = 0 ; k < 10 < i++){
	    if(alunos[k].ativo == 0){
	    	strcpy(alunos[k].id_aluno, id_aluno);
	    	alunos[k].ativo = 1;
	    	break;
	    }
	}
	printf(" \n ------------------------------------------------------------------------\n");
}
	


void consulta_id(Aluno){
	system("cls");
	printf(" \n Digite um código: ");
	scanf("%d", &cod);
	 
	for(i = 0 ; i < 10 ; i++) {
	    if(strcmp(cod, aluno[i].id_aluno) == 0) {
	        printf("\n Registro encontrado! ");
	        posicao = i;
	    } else {
	        posicao = -1;
	    }
	}
	 
	if(posicao = -1) {
	    printf(" \nNão existe o ID na base de alunos!");
	} else {
	    printf(" \nRegistro Encontrado: ");
	    printf(" \nCódigo do aluno: %d ", aluno[posicao].id_aluno);
	    printf(" \nAluno: %s ", aluno[posicao].nm_aluno);
	}

}

void exclui_id(Aluno){
	system("cls");
	int codigo;
	printf("Qual o ID a ser excluído? \n");
	scanf("%d", &codigo);

	for(i = 0 ; i < 10 ; i++) {
	    if(strcmp(codigo, aluno[i].id_aluno) == 0) {
	        printf(" \nCódigo do aluno: %d ", aluno[codigo].id_aluno);
	    	printf(" \nAluno: %s ", aluno[codigo].nm_aluno);
	    	printf("Confirmar exclusão? \n1- Sim\n2- Não");
	    	scanf("%d", &x);

	    	if(x = 1){
				codigo--;
				aluno[codigo].ativo = 0;
			
	      	} else {
	        	posicao = -1;
	    }
	    else
			aluno();
	}





	printf("Código do aluno: \n", aluno[codigo].id_aluno);
	printf("Aluno: \n", aluno[codigo].nm_aluno);
	printf("Confirmar exclusão? \n1- Sim\n2- Não");
	

	if(x = 1)
		codigo--;
		aluno[codigo].ativo = 0;
	else
		aluno();
}

void altera_id(Aluno){
	system("cls");
	

}

 

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

32 minutos atrás, ningumx disse:

Obs: Preciso mudar o "void" ainda.

 

Sem mudar isso seu programa não vai longe. E talvez nem sua nota.  Deveria começar por isso, como eu disse: pelos dados. Nunca por um menu, ou vários menus. Um programa interativo só vai atrasar tudo. Nunca escreva um programa interativo. Não deve se preocupar com isso exceto ao final.

 

32 minutos atrás, ningumx disse:
typedef struct notas {
	int id_aluno;
	int id_nota;
	float vl_nota;
} Notas;

 

As notas não tem sentido sem alunos. Porque não está lá?

 

        printf(" \n=====MENU ALUNO===== ");
        printf(" \n1. Cadastrar");
        printf(" \n2. Consultar por ID");
        printf(" \n3. Excluir por ID");
        printf(" \n4. Alterar por ID");
        printf(" \n5. Relatório");
        printf(" \n6. Voltar");

 

7 printf() de uma linha e não um printf() de 7 linhas? Qual o sentido de chamar 7 vezes a mesma função para fazer a mesma coisa???

 

Considere o simples:

 

    printf("\
    =====MENU NOTAS=====\n\
\n\
    1. Incluir nota do aluno\n\
    2. Alterar nota do aluno\n\
    3. Excluir nota do aluno\n\
    4. Consultar notas do aluno\n\
\n\
    5. Voltar  ");

 

Assim chama uma só vez a função e é muito mais simples de alinhar e prever como vai sair na tela

 

 

32 minutos atrás, ningumx disse:

Após isso, estou fazendo as funções para cada coisa. Porém estou bem confusa no funcionamento do struct no meu programa.

 

Talvez pudesse fazer alguma pergunta sobre isso. O que está confuso?

 

Escreva as funções como te mostrei. É o mais importante. Passe os dados para as funções. Para isso elas são escritas.

 

  • não coloque lógica dentro de um menu
  • não misture entrada de dados com a lógica ou vai levar 10x mais pra testar qualquer coisa mesmo que simples.

 

 

void exclui_id(Aluno){

 

Veja a diferença disso para o que te mostrei: exclui_id() exclui o que de onde? e retorna NADA? Não é o que quer.

 

Você quer excluir um aluno com uma certa id de uma certa turma e quer saber se deu certo. Isso é o que quer então escreva isso.

 

	int res = exclui_id( 42, Fisica_II);


serviria para tentar excluir o aluno com id 42 da turma Fisica_II. E retorna -1 se não tem o cara ou o número que ele tinha na turma se estava lá: o índice do vetor. Entende a diferença?

 

 

 

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@ningumx    você está enviando a struct Aluno , para a função ,  mas nem precisa pois ela é Global , e sua função que faz o cadastro tem três loop's ,  e seria melhor usar um contador para determinar a posição de cada cadastro na struct , e assim não precisa verificar se aquela posição já contém algum cadastro ou não ,  pois incrementando o valor do contador mudará a posição do próximo cadastro ,  e seguindo o modo do seu código ,  seria assim  :

#include     <stdio.h>
#include     <stdlib.h>
#include     <string.h>
typedef struct aluno
{
  int  id_aluno    ;
  char nm_aluno[20];
  int  delete      ;
  int  ativo       ;
  int  qtd         ;
} Aluno            ;
Aluno alunos[10];   /// Maximo 10 Alunos
int i, posicao,cod; /// variAveis Globais
//FUNÇÃO MENU PRINCIPAL
int menu          ();
//Funções ALUNO
int aluno         ();
int cadastro_aluno();
int consulta_id   ();
int exclui_id     ();
int altera_id     ();
int relatorio     ();
//Funções NOTA
int notas         ();
int inclui_nota   ();
int altera_nota   ();
int exclui_nota   ();
int consulta_nota ();
int main()
{
  int opcao1    = 0;
  alunos[0].qtd = 0;
  do
  {
    opcao1 = menu();
    switch (opcao1)
    {
    case 1:
      cadastro_aluno();
      break;
    case 2:
      /// notas();
      break;
    case 3:
      relatorio();
      break;
    case 4:
      printf("\n\t\t\t\tVolte sempre.\n\n");
      return 0;
      break;
    default:
      printf("\n\t\t\t\t\tEscreva um número válido.\n\n");
    }
    system("pause");
  }  while( opcao1 != 4 );
  return 0;
}
//-------------FUNÇÕES MENU--------------
int menu()
{
  char a[10] = { "   "                     };
  l1:
  printf("\t\t\t\t   =====MENU=====   \n\n\n"
         "\t\t\t\t     1. Cadastrar Aluno \n"
         "\t\t\t\t     2. Notas           \n"
         "\t\t\t\t     3. Relatório       \n"
         "\t\t\t\t     4. Sair            \n"
         "\t\t\t\t   _____________________\n"
         "\t\t\t\t   >>>  "                );
  fflush( stdin                            );         
  fgets(                  a, 9, stdin      );
  system(        "cls"                     );
  int opcao1 =      atoi( a                );
  if( opcao1 < 1 || opcao1 > 4             )
  {
    printf("Digitou %d\n OpCAo invAlida . . . !\n",opcao1 );
    goto l1                                 ;
  }
  return         opcao1                     ;
}
int cadastro_aluno()
{
  char aux[10] = {0};
  int cont = alunos[0].qtd;      /// contador de cadastros
  if( cont > 9 )                 /// Maximo 10 Alunos
  {
    printf("o vetor da struct esta Cheio . . . !\n");
    return 0;
  }
  printf("\t\t\t\t=======Cadastro do Aluno=======\n\n\n");
  printf( "Cógido do %d aluno --------: "   , cont + 1  );
  alunos[ cont].id_aluno = atoi(fgets(aux, 9, stdin  )  );
  printf( "Digite o nome do %d aluno -: ",    cont + 1  );
  fgets ( alunos[cont].nm_aluno          ,19, stdin     );    /// fgets pega todos caracteres na linha e + o newLine "enter"
  alunos[cont].nm_aluno[strlen(alunos[cont].nm_aluno)-1] = 0; /// remove newLine pego por fgets
  cont                                    ++             ;
  alunos[0].qtd  =                            cont       ;
  return 0                                               ;
}
int consulta_id()
{
  int cod = 0;
  system("cls");
  printf(" \n Digite um código: ");
  scanf("%d", &cod);
  for(int i = 0 ; i < 10 ; i++)
  {
    if( cod == alunos[i].id_aluno )
    {
      printf("\n Registro encontrado! ");
      posicao = i;
    }
    else
    {
      posicao = -1;
    }
  }
  return 0;
}
int aluno()
{
  return 0;
}
int notas()
{
  return 0;
}
int relatorio()
{
  printf("\tListanDo Alunos Cadastrados\n");
  for(int i=0; i< alunos[0].qtd; i++ )
    printf("Nome ---: %s  \n"
           "Codigo -: %d\n\n" ,
           alunos[i].nm_aluno , 
           alunos[i].id_aluno);
  return 0;
}

 

Link para o comentário
Compartilhar em outros sites

4 horas atrás, devair1010 disse:

 você está enviando a struct Aluno , para a função ,  mas nem precisa pois ela é Global , e sua função que faz o cadastro tem três loop's

 

@devair1010 você deve mudar do outro lado. O errado é existir uma struct GLOBAL. Não se quer isso. É probido em toda parte, escolas e empresas. E é proibido porque não é esperto e só dá prejuízo.

 

4 horas atrás, devair1010 disse:

e seria melhor usar um contador para determinar a posição de cada cadastro na struct , e assim não precisa verificar se aquela posição já contém algum cadastro ou não ,  pois incrementando o valor do contador mudará a posição do próximo cadastro

 

Prefira o simples, e faça igual para as notas:

 

#define LIMITE_ 10
#define LIMITE_N_ 10

typedef struct
{
    unsigned lim;
    unsigned qtd;
    float    valor[LIMITE_N_];
} Nota;

typedef struct 
{
    int  id;
    char nome[50];
    char status;
    Nota nota;
} Aluno;

typedef struct
{
    int      id;
    char     nome[50];
    unsigned limite;        // quantos cabem
    unsigned qtd;           // quantos tem
    Aluno    aln[LIMITE_];  // os alunos
} Turma;

 

E entenda que Turma é um container. De Aluno. E Aluno é um container. De Nota.

 

É o simples. Todos esses exercícios são baseados em simples containers. Se seu modelo for próximo disso seu programa fica trivial. Se ele se afasta...

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Terminei as funções e mudei os menus também.

No entanto, ainda estou com dúvida com a declaração das funções.

Os principais erros são: 

- error: unknown type name 'tab_notas'
  tab_notas tab_notas[30];

 

- declaração implícita das funções

 

- warning: conflicting types for 'cadastro_aluno'
 void cadastro_aluno()

 

Poderia me dar o exemplo com uma para eu poder arrumar?

Agradeço.

 

#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <ctype.h>
#include <math.h>
#include <time.h>


//STRUCTS

typedef struct alunos {
	int id_aluno;
	char nm_aluno[50];
	int quant_notas;
	int delete;
	tab_notas tab_notas[30];
} aluno;


typedef struct notas {
	int id_aluno;
	int id_nota;
	float vl_nota;
} notas;


//-----------------------------------------//

//VARIÁVEIS GLOBAIS
aluno tab_alunos[10];
notas tab_notas[30];
int quant_alunos = 0;
int indice = 1;
int escolha;

//-----------------------------------------//

//MENUS SECUNDÁRIOS

int menu_aluno(){
	int opcao;
    do
    {
        printf("\
				    =====MENU ALUNO=====\n\
				\n\
				    1. Cadastrar\n\
				    2. Consultar por ID\n\
				    3. Exlcuir por ID\n\
				    4. Alterar por ID\n\
				    5. Relatório\n\
				\n\
				    6. Voltar  ");
        scanf("%d", &opcao);
        getchar();

        switch(opcao)
        {
            case 1:
                cadastro_aluno();
            	break;
            case 2:
                consulta_id();
            	break;
            case 3:
                exclui_id();
            	break;   
        	case 4:
        		altera_id();
        		break;
        	case 5:
        		relatorio();
        		break;
        }
    }
    while(opcao != 6);
}


int menu_notas(){
	int opcao;
    do
    {
        printf("\
				    =====MENU NOTAS=====\n\
				\n\
				    1. Incluir nota do aluno\n\
				    2. Alterar nota do aluno\n\
				    3. Excluir nota do aluno\n\
				    4. Consultar notas do aluno\n\
				\n\
				    5. Voltar  ");
        scanf("%d", &opcao);
        switch(opcao)
        {
            case 1:
                inclui_nota();
            	break;
            case 2:
                altera_nota();
            	break;
            case 3:
                exclui_nota();
            	break;   
        	case 4:
        		consulta_nota();
        		break;
        }
    }
    while(opcao != 5);
}



void menu_relatorios(){
	int opcao;
    do
    {
        printf("\
				    =====MENU RELATÓRIO=====\n\
				\n\
				    1. Relatório de notas\n\
				    2. relatório de médias\n\
				\n\
				    3. Voltar  ");
        scanf("%d", &opcao);
        switch(opcao)
        {
            case 1:
                rel_notas();
            	break;
            case 2:
                rel_medias();
            	break;
        }
    }
    while(opcao != 3);
}


//-----------------------------------------//

//FUNÇÕES MENU ALUNO


void cadastro_aluno(){

	quant_alunos++;
	tab_alunos[quant_alunos].id_aluno = quant_alunos;

	printf("\t\t\t\t=======Cadastro do Aluno=======\n\n\n"); 
    printf("Cógido do aluno: %d\n", quant_alunos);


    do {
    	printf("Digite o nome do aluno: ");
	    fgets(tab_alunos[quant_alunos].nm_aluno, 50, stdin);
	    tab_alunos[quant_alunos].nm_aluno[strcspn(tab_alunos[quant_alunos].nm_aluno, "\n\n")] = 0;
	    if(strlen(tab_alunos[quant_alunos].nm_aluno) <= 4)
	    	printf("O nome deve ter mais de três caracteres.\n\n");
	} while (strlen(tab_alunos[quant_alunos].nm_aluno) <= 4);

	tab_alunos[quant_alunos].delete = 0;
	printf("\n\nAluno cadastrado!\n\n");
	printf(" \n ------------------------------------------------------------------------\n");

}



void consulta_id(){
	int i, cod;

	printf("\t\t\t\t=======Consulta do Aluno=======\n\n\n"); 
	printf(" \nCódigo do aluno: \n");
	scanf("%d", &cod);
	getchar();

	for(i = 1 ; i <= quant_alunos ; i++){

		if((cod == tab_alunos[i].id_aluno) && (tab_alunos[i].delete == 0))
			printf("Aluno: %s\n", tab_alunos[i].nm_aluno);
		else
			if((cod == tab_alunos[i].id_aluno) && (tab_alunos[i].delete == 1))
				printf("Não existe o ID na base de alunos!");
		}
	 
	if(cod > quant_alunos || (quant_alunos == 0)) 
	    printf("Aluno não cadastrado!");

	printf(" \n ------------------------------------------------------------------------\n");
}



void exclui_id(){
	int i, cod;
	char opcao;

	printf("\t\t\t\t=======Exclusão de Aluno=======\n\n\n");

	printf("Qual o ID a ser excluído? \n");
	scanf("%d", &cod);


	for(i = 1 ; i <= quant_alunos ; i++) {

		if((cod == tab_alunos[i].id_aluno) && (tab_alunos[i].delete == 0)){

			printf("Confirmar exclusão?\n[S]im\n[N]ão\n");
			getchar();
			fgets(opcao, 2, stdin);
			opcao[0] == toupper(opcao[0]); //deixar maiúscula

			if(strcmp(opcao, "S") == 0){
				tab_alunos[i].delete = 1;
				printf("Aluno excluído!\n");
			}
			else 
				printf("Cancelado.");
		}
		
	}

	if((quant_alunos == 0) || (cod > quant_alunos) || (tab_alunos[i].id_aluno) == 1);
		printf("Aluno não existe na base!\n");

	printf(" \n ------------------------------------------------------------------------\n");
}



void altera_id(){
	int i, cod;
	char opcao[2], nm_aluno2[50];

	printf("\t\t\t\t=======Alterar Aluno=======\n\n\n"); 
	printf(" \nCódigo do aluno: \n");
	scanf("%d", &cod);
	getchar();

	for(i = 1 ; i <= quant_alunos ; i++){

		if((cod == tab_alunos[i].id_aluno) && (tab_alunos[i].delete == 0)){
			printf("Aluno: %s\nNovo nome: \n", tab_alunos[i].nm_aluno);
			fgets(nm_aluno2, 50, stdin);

			printf("Confirmar alteração?\n[S]im\n[N]ão\n");
			getchar();
			fgets(opcao, 2, stdin);
			opcao[0] == toupper(opcao[0]); //deixar maiúscula

			if(strcmp(opcao, "S") == 0){
				strcpy(tab_alunos[i].nm_aluno, nm_aluno2);
				tab_alunos[i].nm_aluno[strcspn(tab_alunos[i].nm_aluno, "\n")] = 0;
				printf("\nNome alterado!\n");
			} else {
				if(strcmp(opcao, "N") == 0);
					printf("Cancelado.\n");
				else
					if((cod == tab_alunos[i].id_aluno) && (tab_alunos[i].delete == 1))
						printf("Aluno não existe na base!");
			}
		}
	}
	printf(" \n ------------------------------------------------------------------------\n");
}




void relatorio(){

	struct tm *data_hora_atual;
		time_t segundos;
		time(&segundos);
		data_hora_atual = localtime(&segundos);
	    int i;
	    char delete[2];

	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("                                           RELATÓRIO DE ALUNOS                                        \n");
	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("          |     ID     |                           NOME                       |  EXCLUÍDO  |\n");

	for(i = 1 ; i <= quant_alunos ; i++){
		printf("|     %d   \t|", tab_alunos[i].id_aluno);
		printf("                      %s\t                   |", tab_alunos[i].nm_aluno);
		printf("      %i     |\n", tab_alunos[i].delete);
	}
	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("___________________________________________________________________________Gerado em %d/%d/%d %i:%i:%i\n", data_hora_atual->tm_mday, data_hora_atual->tm_mon+1, data_hora_atual->tm_year+1900, data_hora_atual->tm_hour, data_hora_atual->tm_min, data_hora_atual->tm_sec);

}	


//-----------------------------------------//

//FUNÇÕES MENU NOTAS

void inclui_nota(){
	int i, cod;
	float nota;

	printf("\t\t\t\t=======Alterar Aluno=======\n\n\n");
	printf("Código do aluno: \n");
	scanf("%d", &cod);
	getchar();

	for(i = 1 ; i <= quant_alunos ; i++){
		if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 0) && (tab_alunos[i].quant_notas <= 4)){
			printf("Aluno: %s\n", tab_alunos[i].nm_aluno);

			for(tab_alunos[i].quant_notas = 1 ; tab_alunos[i].quant_notas <= 3 ; tab_alunos[i].quant_notas++){
				printf("Digite a nota %d (0 a 10): ", tab_alunos[i].quant_notas);
				scanf("%f", &nota);
				tab_alunos[i].tab_notas[tab_alunos[i].quant_notas].vl_nota = nota;
			}
			printf("Nota cadastrada!\n");
		} else{
			if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 1))
				printf("Aluno não existe na base!\n");
		 	else
				if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 0) && (tab_alunos[i].quant_notas > 3))
					printf("Aluno com todas as notas cadastradas!\n");
		}
	}

	if((quant_alunos == 0) || (cod > quant_alunos))
		printf("Aluno não cadastrado!\n");
	printf(" \n ------------------------------------------------------------------------\n");
}



void altera_nota(){
	int i, cod, j, k, nota2;
	float vl_nota2;

	printf("\t\t\t\t=======Alterar Nota=======\n\n\n");
	printf("Código do aluno: \n");
	scanf("%d", &cod);
	getchar();

	for(i = 1 ; i <= quant_alunos ; i++){
		if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 0) && (tab_alunos[i].quant_notas != 0)){
			printf("Aluno: %s\n", tab_alunos[i].nm_aluno);

			for(j = 1 ; j <= quant_alunos ; j++)
				printf("Nota [%d]: %.2f\n", j, tab_alunos[i].tab_notas[j].vl_nota);

			for(k = 1 ; k <= 2 ; k++){
				printf("Qaul nota deseja alterar? ");
				scanf("%d", &nota2);


				if(nota2 < 3){
					printf("Digite a nova nota [%d] (0 a 10): ", nota2);
					scanf("%f", vl_nota2);
					tab_alunos[i].tab_notas[k].vl_nota = vl_nota2;
					printf("Nota alterada!\n");
				}
				else
					printf("Nota não existe!\n");
			}
		}
		else
			if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 1))
				printf("Aluno não existe na base!\n");
			else
				if (tab_alunos[i].quant_notas == 0)
					printf("Aluno sem notas cadastradas!\n");
	}
	if((quant_alunos == 0) || (cod > quant_alunos))
		printf("Aluno não cadastrado!\n");
	
	printf(" \n ------------------------------------------------------------------------\n");
}




void exclui_nota(){
	int i, cod, j, k, nota_exc;

	printf("\t\t\t\t=======Alterar Nota=======\n\n\n");
	printf("Código do aluno: \n");
	scanf("%d", &cod);
	getchar();

	for(i = 1 ; i <= quant_alunos ; i++){
		if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 0) && (tab_alunos[i].quant_notas != 0)){
			printf("Aluno: %s\n", tab_alunos[i].nm_aluno);

			for(j = 1 ; j <= quant_alunos ; j++)
				printf("Nota [%d]: %.2f\n", j, tab_alunos[i].tab_notas[j].vl_nota);

			for(k = 1 ; k <= 2 ; k++){
				printf("Qual nota deseja excluir? ");
				scanf("%d", &nota_exc);

				if(nota_exc < 3)
					if(nota_exc <= 3){
						tab_alunos[i].tab_notas[k].vl_nota == 0;
						printf("Nota excluída!\n");
					}
				else
					printf("Nota inválida!\n");
			}
		} else{
			if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 1))
				printf("Aluno não existe na base!\n");
			else
				if(tab_alunos[i].quant_notas == 0)
					printf("Aluno sem notas cadastradas!\n");
		}
	}
	if((quant_alunos == 0) || (cod > quant_alunos))
		printf("Aluno não cadastrado!\n");

	printf(" \n ------------------------------------------------------------------------\n");

}



void consulta_nota(){
	int i, cod, j, k;

	printf("\t\t\t\t=======Consultar Nota=======\n\n\n");
	printf("Código do aluno: \n");
	scanf("%d", &cod);
	getchar();

	for(i = 1 ; i <= quant_alunos ; i++){
		if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 0) && (tab_alunos[i].quant_notas != 0)){
			printf("Aluno: %s\n", tab_alunos[i].nm_aluno);

			for(j = 1 ; j <= quant_alunos ; j++)
				printf("Nota [%d]: %.2f\n", j, tab_alunos[i].tab_notas[j].vl_nota);

		} else{
			if((tab_alunos[i].id_aluno == cod) && (tab_alunos[i].delete == 1))
				printf("Aluno não existe na base!\n");
			else
				if(tab_alunos[i].quant_notas == 0)
					printf("Aluno sem notas cadastradas!\n");
		}
	}
	if((quant_alunos == 0) || (cod > quant_alunos))
		printf("Aluno não cadastrado!\n");

	printf(" \n ------------------------------------------------------------------------\n");

}

//-----------------------------------------//

//FUNÇÕES MENU RELATÓRIO

void rel_notas(){
	system("cls");

	struct tm *data_hora_atual;
	time_t segundos;
	time(&segundos);
	data_hora_atual = localtime(&segundos);
	int i, k;
	    

	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("                                           RELATÓRIO DE NOTAS                                         \n");
	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("|   ID   |                     NOME                    |  NOTA 1  |  NOTA 2  |  NOTA 3  |\n");

	for(i = 1 ; i <= quant_alunos ; i++){
		printf("|     %d   \t|", tab_alunos[i].id_aluno);
		printf("                      %s\t                   |", tab_alunos[i].nm_aluno);
		
		for(k = 1 ; k <= 3 ; k++)
			printf("   %.2f   |", tab_alunos[i].tab_notas[k].vl_nota);

		printf("\n")/
	}
	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("___________________________________________________________________________Gerado em %d/%d/%d %i:%i:%i\n", data_hora_atual->tm_mday, data_hora_atual->tm_mon+1, data_hora_atual->tm_year+1900, data_hora_atual->tm_hour, data_hora_atual->tm_min, data_hora_atual->tm_sec);

}	



void rel_medias(){

	struct tm *data_hora_atual;
	time_t segundos;
	time(&segundos);
	data_hora_atual = localtime(&segundos);
	int i;
	    

	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("                                           RELATÓRIO DE MÉDIAS                                        \n");
	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("|   ID   |                         NOME                        |  MÉDIA  |\n");

	for(i = 1 ; i <= quant_alunos ; i++){
		printf("|     %d   \t|", tab_alunos[i].id_aluno);
		printf("                      %s\t                   |", tab_alunos[i].nm_aluno);
		printf("   %.2f  |\n", (tab_alunos[i].tab_notas[3].vl_nota + tab_alunos[i].tab_notas[1].vl_nota + tab_alunos[i].tab_notas[2].vl_nota) / 3);
	}

	printf("\n\n\n\n\n__________________________________________________________________________________\n\n\n\n\n");
	printf("___________________________________________________________________________Gerado em %d/%d/%d %i:%i:%i\n", data_hora_atual->tm_mday, data_hora_atual->tm_mon+1, data_hora_atual->tm_year+1900, data_hora_atual->tm_hour, data_hora_atual->tm_min, data_hora_atual->tm_sec);
}



//-----------------------------------------//

int main(){
	setlocale(LC_ALL, "");

	do {
		struct tm *data_hora_atual;
		time_t segundos;
		time(&segundos);
		data_hora_atual = localtime(&segundos);
    	printf("Acesso em %d/%d/%d %i:%i:%i\n", data_hora_atual->tm_mday, data_hora_atual->tm_mon+1, data_hora_atual->tm_year+1900, data_hora_atual->tm_hour, data_hora_atual->tm_min, data_hora_atual->tm_sec);

    	int opcao;
    	printf("\
				    =====MENU PRINCIPAL=====\n\
				\n\
				    1. Menu Aluno\n\
				    2. Menu Notas\n\
				    3. Menu Relatórios\n\
				\n\
				    4. Voltar  ");
	    scanf("%d", &escolha);
	    getchar();
	

		switch (escolha){
			case 1:
				menu_aluno();
				break;
			case 2:
				menu_notas();
				break;
			case 3:
				menu_relatorios();
				break;
		}
	} while(escolha != 4);

	return 0;
}

 

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

  • Solução
26 minutos atrás, ningumx disse:

Terminei as funções e mudei os menus também.

No entanto, ainda estou com dúvida com a declaração das funções.

Os principais erros são: 

- error: unknown type name 'tab_notas'
  tab_notas tab_notas[30];

 

- declaração implícita das funções

 

- warning: conflicting types for 'cadastro_aluno'
 void cadastro_aluno()

 

Você continua insistindo com o que eu te disse pra não fazer 😉 

 

E eu te disse pra mudar ou teria muito trabalho a toa.

 

E o que está acontecendo?

 

Você está tendo muito trabalho. A toa.

 

Que posso dizer mais? 

 

Veja isso:

 

23 horas atrás, arfneto disse:

NUNCA use funções void e sem argumentos. De pouco ou nada vão servir. Só vão funcionar uma vez para um certo dado. Ninguém faria um programa para rodar uma vez só com um dado só se fosse ensinado corretamente.

 

20 horas atrás, ningumx disse:

Declarei uma série de funções pois terá mais de um menu, então preferi separar cada coisa: 

Obs: Preciso mudar o "void" ainda.

 

20 horas atrás, arfneto disse:

Sem mudar isso seu programa não vai longe. E talvez nem sua nota.  Deveria começar por isso, como eu disse: pelos dados. Nunca por um menu, ou vários menus. Um programa interativo só vai atrasar tudo. Nunca escreva um programa interativo. Não deve se preocupar com isso exceto ao final.

 

Pois é.

 

Pode escrever como quiser. Mas provavelmente deveria fazer como eu disse.

 

De volta ao código que não compila

 

31 minutos atrás, ningumx disse:

tab_notas tab_notas[30];

 

Que seria isso? Qual o tipo de tab_notas? Não pode ser tab_notas...

 

E porque as notas não estão DENTRO de Aluno? Qual o propósito de deixar separado e ter que colocar um campo id para associar um com o outro se um não existe sem o outro? Já falei disso e mostrei um exemplo

 

 

 

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

🙂

 

E agora? Hora de terminar o programa

Temos um mecanismo para criar, mostrar e apagar as matrizes, de qualquer tamanho aceito no programa. O que falta é só preencher a matriz com os dados esperados e mostrar a matriz antes e depois. E já tem a função que mostra, a que cria e a que apaga.

 

Então falta apenas

 

    int     preenche(Matriz* matriz);


e a vida segue.
 

O exercício todo é essa função: todo o resto deveria estar separado. Mas já está. E assim se pode usar em outros programas. E é claro que isso que foi feito até aqui pode ter sido copiado de programas antigos escritos desse modo simples. Se você já escreveu outro programa que criava matrizes quadradas e não tinha nada para copiar para esse programa aqui então sabe que aprendeu algo agora 😄 

 

 

Como preencher `Matriz`afinal?
 

Precisamos de números inválidos e válidos. E como a sequência é aleatória não dá pra saber se vai preencher por exemplo os múltiplos de `13` primeiro e depois a diagonal com os múltiplos de `5`. E é claro que números podem se repetir e isso é irrelevante.
Considere o número `715`, múltiplo de `5` `11` e `13`. É claro que esse número pode aparecer em qualquer posição da `Matriz`: se ainda não completou a diagonal vai ficar lá na diagonal. Mas se completou mas não completou os múltiplos de 11 vai estar acima da diagonal. E se terminou esses também 715 vai ficar abaixo como múltiplo de 13.

Uma vez que a ordem está definida como `N` temos que a diagonal vai ter `N` valores, e acima e abaixo vão estar `(N  * N) - N` valores. Por exemplo uma matriz `7x7` vai ter `49` valores, `7` na diagonal principal, `21` acima e `21` abaixo dela.   

 

Um pouco de matemática

Na função vamos preencher a matriz usando valores recebidos de `rand()`. Basta um único loop. Um vetor `fase[]` controla o preenchimento das 3 áreas da matriz. No exemplo são números entre 1 e 1000 inclusive.
 

#define INVALIDO_ 0
#define PRINCIPAL_ 1
#define ABAIXO_ 3
#define ACIMA_ 2
    const char* msg[] = {
        "numero invalido",
        "diagonal principal preenchida",
        "não existe espaco acima da diagonal principal",
        "não existe espaco abaixo da diagonal principal"};
    const int limite  = 1000;
    int       num     = 0;

    unsigned ac_l = 0;  // multiplos de 11 a partir de (0,1)
    unsigned ac_c = 1;
    unsigned ab_l = 1;  // multiplos de 13 a partir de (1,0)
    unsigned ab_c = 0;

    // define quantos numeros vão onde
    int fase[] = {
        mtr->ord,  // na diagonal principal
        (mtr->ord * mtr->ord - mtr->ord)/2, // acima
        0
    };
    fase[2] = fase[1]; // igual acima e abaixo
    printf(
        "\nPreenchendo matriz [%lux%lu]: %d valores na "
        "diagonal, %d acima, %d abaixo\n\n\n",
        mtr->ord, mtr->ord, fase[0], fase[1], fase[2]);

 

  •  os `#define` servem para não ter que lembrar qual o índice da mensagem E poder ficar com elas no mesmo vetor simplifica possíveis alterações
  • `limite` é o óbvio aqui: com `1000` vai gerar números entre 1 e 1000 inclusive.
  • os valores de `fase[]` são os totais de números a encontrar. Sáo calulados e mostrados a seguir. Eis uma saída do `printf()` que mostra os valores

 

    Preenchendo matriz [20x20]: 20 valores na diagonal, 190 acima, 190 abaixo

 

  •  `controle` é o produto dos 3 fatores que usamos. A cada parte preenchida dividimos `controle` pelo múltiplo correspondente e assim se pode encerrar o loop quando `controle` for `1`.

 

  • Esse é o "cálculo" de cada número:

 

        num = 1 + rand() % limite;

 

  •  para os múltiplos de `11` começa a preencher em [0,1] e não atravessa a diagonal
  • para os múltiplos de `13` começa a preencher em [1,0] e também não atravessa a diagonal

 

E é só isso.

 

 

para múltiplos de `5`
 

        // multiplos de 5 na diagonal principal
        if ((fase[0] > 0)&&(num % 5 == 0))
        {
            mtr->M[fase[0] - 1][fase[0] - 1] = num;
            fase[0] -= 1;
            if (fase[0] < 1)
            {
                printf("%s\n", msg[PRINCIPAL_]);
                controle /= 5;
            }
            continue;  // usou o numero
        };  // fim: multiplo de 5


     

O simples: coloca o número na diagonal. Quando termina de preencher mostra a mensagem pedida no enunciado. Note o comando `continue` para passar para o próximo número apenas se usou esse número aqui, de modo que `55` por exemplo pode aparecer como múliplo de `11` se quando ele foi sorteado a diagonal principal já estava completa:
 

	diagonal principal preenchida


para múltiplos de `11`
 

       // multiplos de 11 acima
        if ((fase[1] > 0)&&(num % 11 == 0))
        {
            mtr->M[ac_l][ac_c] = num;  // multiplo de 11
            fase[1] -= 1;
            if (ac_c < (mtr->ord - 1))
                ac_c += 1;
            else
            {
                ac_l += 1;
                ac_c = 1 + ac_l;
            };
            if (fase[1] < 1)
            {
                printf("%s\n", msg[ACIMA_]);
                controle /= 11;
            }
            continue;
        };  // fim: multiplo de 11


 
É igual ao caso do `5`, mas deve ajustar linha e coluna para manter os valores na parte superior da matriz, usando `ac_l` e `ac_c`. O `continue` para o próximo número só executa se esse número foi usado aqui. Assim por exemplo `143` que é `11*13` vai ser usado como múltiplo de `13` se os múltiplos de `11` já estiverem preenchidos.
 

para múltiplos de `13`
 

        // multiplos de 13 abaixo da diagonal
        if ((fase[2] > 0)&&(num % 13 == 0))
        {
            mtr->M[ab_l][ab_c] = num;  // multiplo de 13
            fase[2] -= 1;
            if (ab_c < (ab_l - 1))
                ab_c += 1;
            else
            {
                ab_l += 1;
                ab_c = 0;
            };
            if (fase[2] < 1)
            {
                printf("%s\n", msg[ABAIXO_]);
                controle /= 13;
            }
            continue;
        };  // fim: multiplo de 13


 

E é claro igualzinho e foi copiado um do outro.

 

 

### A função que faltava: `preenche(Matriz* matriz)` ###


 

int preenche(Matriz* mtr)
{
#define INVALIDO_ 0
#define PRINCIPAL_ 1
#define ABAIXO_ 3
#define ACIMA_ 2
    const char* msg[] = {
        "numero invalido",
        "diagonal principal preenchida",
        "não existe espaco acima da diagonal principal",
        "não existe espaco abaixo da diagonal principal"};
    const int limite  = 1000;
    int       num     = 0;

    unsigned ac_l = 0;  // multiplos de 11 a partir de (0,1)
    unsigned ac_c = 1;
    unsigned ab_l = 1;  // multiplos de 13 a partir de (1,0)
    unsigned ab_c = 0;

    // define quantos numeros vão onde
    int fase[] = {
        mtr->ord,  // na diagonal principal
        (mtr->ord * mtr->ord - mtr->ord)/2, // acima
        0
    };
    fase[2] = fase[1]; // igual acima e abaixo
    printf(
        "\nPreenchendo matriz [%lux%lu]: %d valores na "
        "diagonal, %d acima, %d abaixo\n\n\n",
        mtr->ord, mtr->ord, fase[0], fase[1], fase[2]);

    // fica no loop ate preencher tudo
    int controle = 5 * 11 * 13;  // os multiplos
    while (controle > 1)
    {
        num = 1 + rand() % limite;  // novo numero
        // multiplos de 5 na diagonal principal
        if ((fase[0] > 0)&&(num % 5 == 0))
        {
            mtr->M[fase[0] - 1][fase[0] - 1] = num;
            fase[0] -= 1;
            if (fase[0] < 1)
            {
                printf("%s\n", msg[PRINCIPAL_]);
                controle /= 5;
            }
            continue;  // usou o numero
        };  // fim: multiplo de 5
        // multiplos de 11 acima
        if ((fase[1] > 0)&&(num % 11 == 0))
        {
            mtr->M[ac_l][ac_c] = num;  // multiplo de 11
            fase[1] -= 1;
            if (ac_c < (mtr->ord - 1))
                ac_c += 1;
            else
            {
                ac_l += 1;
                ac_c = 1 + ac_l;
            };
            if (fase[1] < 1)
            {
                printf("%s\n", msg[ACIMA_]);
                controle /= 11;
            }
            continue;
        };  // fim: multiplo de 11
        // multiplos de 13 abaixo da diagonal
        if ((fase[2] > 0)&&(num % 13 == 0))
        {
            mtr->M[ab_l][ab_c] = num;  // multiplo de 13
            fase[2] -= 1;
            if (ab_c < (ab_l - 1))
                ab_c += 1;
            else
            {
                ab_l += 1;
                ab_c = 0;
            };
            if (fase[2] < 1)
            {
                printf("%s\n", msg[ABAIXO_]);
                controle /= 13;
            }
            continue;
        };  // fim: multiplo de 13
        // ou sao invalidos
        printf("\t%d: %s\n", num, msg[INVALIDO_]);
    };  // while()
    return 0;
}



Eis o programa todo, incluindo a tal função 

 

### Um programa completo ###

 

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

typedef struct
{
    unsigned ord;  // linhas/colunas da matriz
    int**    M;    // a matriz
} Matriz;

Matriz* apaga(Matriz*);
Matriz* cria(unsigned);
int     mostra(Matriz*, const char*);
int     preenche(Matriz*);

int main(int argc, char** argv)
{
    const long semente = 20221114;  // para o gerador
    srand(semente);                 // prepara o gerador

    unsigned ordem = 5;  // matriz 5x5 padrão
    unsigned val   = 0;
    if (argc > 1)
    {
        val = atoi(argv[1]);
        if ((val > 1) && (val < 21)) ordem = val;
    };
    printf("Usando matriz [%lux%lu]\n", ordem, ordem);
    Matriz* tst = cria(ordem);
    mostra(tst, "\n[Matriz antes de ser preenchida]\n");
    preenche(tst);
    mostra(tst, "\n[Matriz preenchida]\n");
    tst = apaga(tst);
}

Matriz* apaga(Matriz* mtr)
{  // apaga a tal matriz
    if (mtr == NULL) return NULL;
    printf("Apaga matriz [%lux%lu]\n", mtr->ord, mtr->ord);
    // apaga as colunas
    for (unsigned l = 0; l < mtr->ord; l += 1)
        free(mtr->M[l]);
    // apaga as linhas
    free(mtr->M);
    // apaga a matriz
    free(mtr);
    return NULL;  // retorna NULL
}

Matriz* cria(unsigned ordem)
{  // ordem entre 2 e 10 (inclusive)
    // se fora dos limites assume 5
    if ((ordem < 2) || (ordem > 20)) ordem = 5;
    // cria uma Matriz
    Matriz* mtr = (Matriz*)malloc(sizeof(Matriz));
    mtr->ord    = ordem;  // claro
    // cria as linhas
    mtr->M  = (int**)malloc(ordem * sizeof(int*));
    int val = 0;
    for (unsigned l = 0; l < ordem; l++)
    {  // cria as colunas
        mtr->M[l] = (int*)malloc(ordem * sizeof(int));
        // pra testar numera os elementos
        for (unsigned c = 0; c < ordem; c += 1)
            mtr->M[l][c] = ++val;
    }
    return mtr;  // retorna Matriz ok
}

int mostra(Matriz* mtr, const char* msg)
{
    if (mtr == NULL) return -1;
    if (msg != NULL) printf("%s", msg);
    printf("Matriz [%lux%lu]\n", mtr->ord, mtr->ord);

    for (unsigned i = 0; i < mtr->ord; i += 1)
    {
        for (unsigned j = 0; j < mtr->ord; j += 1)
            printf("%5d ", mtr->M[i][j]);
        printf("\n");  // fim da linha
    }
    printf("\n");  // fim da matriz
    return 0;
}

int preenche(Matriz* mtr)
{
#define INVALIDO_ 0
#define PRINCIPAL_ 1
#define ABAIXO_ 3
#define ACIMA_ 2
    const char* msg[] = {
        "numero invalido", "diagonal principal preenchida",
        "não existe espaco acima da diagonal principal",
        "não existe espaco abaixo da diagonal principal"};
    const int limite  = 1000;
    int       num     = 0;

    unsigned ac_l = 0;  // multiplos de 11 a partir de (0,1)
    unsigned ac_c = 1;
    unsigned ab_l = 1;  // multiplos de 13 a partir de (1,0)
    unsigned ab_c = 0;

    // define quantos numeros vão onde
    int fase[] = {
        mtr->ord,  // na diagonal principal
        (mtr->ord * mtr->ord - mtr->ord)/2, // acima
        0
    };
    fase[2] = fase[1]; // igual acima e abaixo
    printf(
        "\nPreenchendo matriz [%lux%lu]: %d valores na "
        "diagonal, %d acima, %d abaixo\n\n\n",
        mtr->ord, mtr->ord, fase[0], fase[1], fase[2]);

    // fica no loop ate preencher tudo
    int controle = 5 * 11 * 13;  // os multiplos
    while (controle > 1)
    {
        num = 1 + rand() % limite;  // novo numero
        // multiplos de 5 na diagonal principal
        if ((fase[0] > 0)&&(num % 5 == 0))
        {
            mtr->M[fase[0] - 1][fase[0] - 1] = num;
            fase[0] -= 1;
            if (fase[0] < 1)
            {
                printf("%s\n", msg[PRINCIPAL_]);
                controle /= 5;
            }
            continue;  // usou o numero
        };  // fim: multiplo de 5
        // multiplos de 11 acima
        if ((fase[1] > 0)&&(num % 11 == 0))
        {
            mtr->M[ac_l][ac_c] = num;  // multiplo de 11
            fase[1] -= 1;
            if (ac_c < (mtr->ord - 1))
                ac_c += 1;
            else
            {
                ac_l += 1;
                ac_c = 1 + ac_l;
            };
            if (fase[1] < 1)
            {
                printf("%s\n", msg[ACIMA_]);
                controle /= 11;
            }
            continue;
        };  // fim: multiplo de 11
        // multiplos de 13 abaixo da diagonal
        if ((fase[2] > 0)&&(num % 13 == 0))
        {
            mtr->M[ab_l][ab_c] = num;  // multiplo de 13
            fase[2] -= 1;
            if (ab_c < (ab_l - 1))
                ab_c += 1;
            else
            {
                ab_l += 1;
                ab_c = 0;
            };
            if (fase[2] < 1)
            {
                printf("%s\n", msg[ABAIXO_]);
                controle /= 13;
            }
            continue;
        };  // fim: multiplo de 13
        // ou sao invalidos
        printf("\t%d: %s\n", num, msg[INVALIDO_]);
    };  // while()
    return 0;
}


Claro que a única novidade aqui é a função `preenche()` que só tem um loop: sorteia números e tenta colocar na matriz até... preencher tudo.

 

### saída do exemplo completo ###
 

Usando matriz [3x3]

[Matriz antes de ser preenchida]
Matriz [3x3]
    1     2     3
    4     5     6
    7     8     9


Preenchendo matriz [3x3]: 3 valores na diagonal, 3 acima, 3 abaixo


        317: numero invalido
        948: numero invalido
        734: numero invalido
        382: numero invalido
        877: numero invalido
        927: numero invalido
        281: numero invalido
        918: numero invalido
        578: numero invalido
        19: numero invalido
        821: numero invalido
        882: numero invalido
        857: numero invalido
diagonal principal preenchida
        149: numero invalido
        116: numero invalido
        433: numero invalido
        541: numero invalido
        959: numero invalido
não existe espaco abaixo da diagonal principal
        82: numero invalido
        857: numero invalido
        705: numero invalido
não existe espaco acima da diagonal principal

[Matriz preenchida]
Matriz [3x3]
  480   418    55
  169   810   286
  676   728   250

Apaga matriz [3x3]


 

E se vê que `55` apareceu quando a diagonal principal já estava preenchida e assim ficou acima como múltiplo de `11`. 

 

### Um exemplo `20x20` ###

 

Sem as mensagens de **número inválido**, eis uma saída para ordem `20`   

Usando matriz [20x20]

[Matriz antes de ser preenchida]
Matriz [20x20]
    1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16    17    18    19    20
   21    22    23    24    25    26    27    28    29    30    31    32    33    34    35    36    37    38    39    40
   41    42    43    44    45    46    47    48    49    50    51    52    53    54    55    56    57    58    59    60
   61    62    63    64    65    66    67    68    69    70    71    72    73    74    75    76    77    78    79    80
   81    82    83    84    85    86    87    88    89    90    91    92    93    94    95    96    97    98    99   100
  101   102   103   104   105   106   107   108   109   110   111   112   113   114   115   116   117   118   119   120
  121   122   123   124   125   126   127   128   129   130   131   132   133   134   135   136   137   138   139   140
  141   142   143   144   145   146   147   148   149   150   151   152   153   154   155   156   157   158   159   160
  161   162   163   164   165   166   167   168   169   170   171   172   173   174   175   176   177   178   179   180
  181   182   183   184   185   186   187   188   189   190   191   192   193   194   195   196   197   198   199   200
  201   202   203   204   205   206   207   208   209   210   211   212   213   214   215   216   217   218   219   220
  221   222   223   224   225   226   227   228   229   230   231   232   233   234   235   236   237   238   239   240
  241   242   243   244   245   246   247   248   249   250   251   252   253   254   255   256   257   258   259   260
  261   262   263   264   265   266   267   268   269   270   271   272   273   274   275   276   277   278   279   280
  281   282   283   284   285   286   287   288   289   290   291   292   293   294   295   296   297   298   299   300
  301   302   303   304   305   306   307   308   309   310   311   312   313   314   315   316   317   318   319   320
  321   322   323   324   325   326   327   328   329   330   331   332   333   334   335   336   337   338   339   340
  341   342   343   344   345   346   347   348   349   350   351   352   353   354   355   356   357   358   359   360
  361   362   363   364   365   366   367   368   369   370   371   372   373   374   375   376   377   378   379   380
  381   382   383   384   385   386   387   388   389   390   391   392   393   394   395   396   397   398   399   400


Preenchendo matriz [20x20]: 20 valores na diagonal, 190 acima, 190 abaixo


diagonal principal preenchida
não existe espaco acima da diagonal principal
não existe espaco abaixo da diagonal principal

[Matriz preenchida]
Matriz [20x20]
  105   418   286   154   671    99   484   682    77   231   495   924   638   220   396   605   330   638   154   451
  169   705   451   165   561   968   440   715   704   495   352   473    99   473   484   110   297   440   770   924
  676   728   485   858   275   209   891   264   121   121   495   880   462   341   440   253   627   253   583   638
  169   364    26   190   594   814   319   319   473   341    44   627   132   583   616   231   429   253   198   418
  728   585   702   975   790   869   352   451   264    99   110   572   682   165   902   847   660   759    22   814
  169   702    13   299   494   940    88   374   110   748   528   671   209   748   583   748   517   143   319   286
  533    78   156   104   390   416   235   770   891   418    44   737   924   352    66   946   583   484   792   154
  663   754   117    65   325   767   845   930   297   671   473   176   638   396   198   220    33    22   913   968
  624   169   533   611   325   455   104   559   610   374   660   231   913   396   627   506   396   319   396   407
  338   611   533   598   832   247   676   611   585   510   946    99    88   517    88    44   847   891   836   594
   91    13   208   260   949   169    91   247   273   637   670    33   495   198   407   979   825   605   187   803
  390   910   663    26    39   403   494   923   754   221   260   280   308   671   836   792   341   572   671   583
  403   871   884   455   546   130   689   754   676   260   208   208   570   660   660   165   704   935   407   297
  975   767   273   104    52   234   351   507   221   650   377   923   611   140   847   957   638   715   770   528
  455   364   819   780   949    65   234    39   663   377   689   260   559   195   260   528   583   275   341   660
   91   351   455   117   351   507   208   728   962   598   689   156   923   611   104   705   429   143   737   880
  897   923   182   936    13   936   975   273   195   390   533   598   377   832   130    91    55   352   638   451
  481   338   845   520   559   234   299   221   234   728   819   351   364   923   507   793   871   480   704   154
  546   520   598   247   182   689   689   117   273   637   182   494   156    91   988   806   247   299   810   814
  351   247   728   494   338   143    91   845   598   650   650   728   663   598   208   780   611   741   260   250

Apaga matriz [20x20]


 

E note o 715 na lista na segunda linha, o único múltiplo comum menor que 1000.

 

## Se você leu até aqui ##
 

 

Esse foi um programa escrito em 3 passos, em torno dos dados do enunciado. E rodou certo (assim parece) na primeira vez em cada passo, porque tudo que se acrescentou a cada passo foi um mínimo. Nesse caso aqui uma função só.

  • Amei 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!