Ponteiro para struct | Como inicializar vetor de struct dentro da struct? | C++ | Dúvidas !
Pessoal estou com uma duvida grande, estou estudando estrutura de dados e como consequencia cheguei a parte de ponteiros, ja entendi a questão do conceito de ponteiro, no qual o ponteiro é uma variável que guarda o endereço de memoria de uma outra variável. Ja quando a gente entra na questão da alocação dinamica (malloc, calloc, realloc e free) comecei a me bater com uma coisa em específico. Estou fazendo um programinha de Agenda telefonica, que tem uma "struct AGENDA", que tem parametros como "nome" e um vetor dinamico de outra struct "struct CONTATO" que armazena todos os contatos desejados pelo usuario dinamicamente. Certo, agora que entendeu um pouco o escopo do programa, a minha dificuldade é a seguinte, como eu inicializo o vetor "struct CONTATO" que está dentro da "struct AGENDA" que foi inicializada dinamicamente? Abaixo segue o código que fiz até o momento, existem varios erros, mas estou corrigindo a medida que vou percebendo, mas a priore so quero inicializar as estruturas (struct) corretamente e estou me bantendo com a inicialização do vetor de "struct CONTATO" dentro da "struct AGENDA". Caso não tenha entendido algo, comenta aí que tento explicar melhor minha dúvida! Segue código abaixo
#include <iostream>
#include <string>
using namespace std;
typedef struct contato {
string nome;
string telefone;
string email;
} CONTATO;
typedef struct agenda {
string nome;
CONTATO *listaContato;
} AGENDA;
AGENDA *criarAgenda(string); // RETORNA UM ENDEREÇO DE MEMORIA
void adicionarContato(AGENDA *); // RECEBE ENDEREÇO DE MEMORIA CORRESPONDENTE A
// AGENDA CRIADA COMO PARAMETRO
void editarContato(string);
void excluirContato(string);
void listarContato();
int main() {
// ADICIONANDO CHARACTERES ESPECIAIS
setlocale(LC_ALL, "Portuguese");
// DECLARANDO VARIAVEIS
string nome;
AGENDA *ptrAgenda;
int sairMenu = 0, opcaoMenu;
// ENTRADA DE DADOS
cout << "Digite o seu nome: " << endl;
cin >> nome;
cout << "\n" << endl;
ptrAgenda = criarAgenda(nome);
// MENU
do {
cout << "Agenda de " << nome << ": " << endl;
cout << "\n" << endl;
cout << "1 - Adicionar Contato " << endl;
cout << "2 - Listar Contatos " << endl;
cout << "3 - Excluir Contato " << endl;
cout << "4 - Fechar Agenda " << endl;
cin >> opcaoMenu;
switch (opcaoMenu) {
case 1:
adicionarContato(ptrAgenda);
break;
case 2:
// listarContato();
break;
case 3:
// excluirContato("string");
break;
case 4:
sairMenu++;
break;
default:
cout << "Opção invalida, favor tentar novamente! " << endl;
break;
}
} while (sairMenu == 0);
return 0;
}
// FUNCIONALIDADES
AGENDA *criarAgenda(string nomeUsuario) {
AGENDA *novaAgenda;
novaAgenda = (AGENDA *)malloc(sizeof(AGENDA)); // RESERVANDO ENDEREÇO DE MEMORIA PARA AGENDEA
cout << "Criou ponteiro para agenda - OK " << endl; // SAÍDA DE TEXTO PARA SABER EM QUAL LINHA ESTÁ TRAVANDO O CODIGO
novaAgenda->nome = nomeUsuario;
cout << "Adicionou o nome de usuario, sendo ele - OK " << novaAgenda->nome << endl;
novaAgenda->listaContato = (CONTATO *)malloc(sizeof(CONTATO));
novaAgenda->listaContato->nome = "NULL";
novaAgenda->listaContato->telefone = "NULL";
novaAgenda->listaContato->email = "NULL";
cout << "Criou lista contato de boa aparentemente, nome: " << endl;
return novaAgenda;
};
void adicionarContato(AGENDA *agenda) {
// ENTRADA
string nomeContato, telContato, emailContato;
cout << "Digite o nome do contato: " << endl;
cin >> nomeContato;
cout << "Digite o telefone do contato: " << endl;
cin >> telContato;
cout << "Digite o email do contato: " << endl;
cin >> emailContato;
// PROCESSAMENTO
int tamContato =
(int)(sizeof(agenda[0].listaContato)) /
(int)(sizeof(agenda[0].listaContato[0])); // descobrindo tamanho da array
cout << "tamanho array: " << tamContato << endl;
agenda[0].listaContato[tamContato].nome = nomeContato;
agenda[0].listaContato[tamContato].telefone = telContato;
agenda[0].listaContato[tamContato].email = emailContato;
};
Apesar do meu post não ter alcançado muita gente, encontrei a resposta, consecutivamente vim trazer pra vocês, caso haja alguem com a mesma dúvida. Ao estudar a materia de LP na faculdade o professor estava passando todas as estruturas de dados em C, eu quis implementar alguns conceitos de C em C++, isso tava acarretando em diversos erros de compilação que teoricamente não deveriam acontecer. Alterei todo o codigo conforme percebi e ja consegui desenvolver duas funcionalidade, a função "adicionarContato()" e a função "listarContatos()", porem estou agora pensando como resolver a questão dos vetores alocados dinamicamente, consigo adicionar um item, mas ele sobre escreve inves de adicionar mais um espaço de memoria, estou corrigindo o codigo mas ainda há varios erros de logica e sintaxe, mas é justamente por isso que estou trazendo aqui, segue o código abaixo:
Obs.: Estou pensando em usar a estrutura de Pilha para criar a lista de contatos. Mas ja me disseram que pra esse caso Lista é melhor, caso tenha alguma dica, favor comentar abaixo!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct contato {
char nome[30];
char telefone[30];
char email[30];
struct contato *primeiro;
struct contato *ultimo;
} CONTATO;
typedef struct agenda {
char nome[30];
CONTATO *listaContato;
} AGENDA;
AGENDA *criarAgenda(char[30]);
void adicionarContato(AGENDA *);
void listarContato(AGENDA *);
int main() {
// DECLARANDO VARIAVEIS
char nome[30];
AGENDA *ptrAgenda;
int sairMenu = 0;
int opcaoMenu;
// ENTRADA DE DADOS
printf("Digite um nome \n");
fgets(nome, 30, stdin);
strtok(nome, "\n");
// PROCESSAMENTO
ptrAgenda = criarAgenda(nome);
if (ptrAgenda == NULL) {
printf("Erro ao alocar a agenda");
} else {
// MENU
do {
printf("Bem vindo - %s \n\n", ptrAgenda->nome);
printf("1 - Adicionar Contato \n");
printf("2 - Listar Contatos \n");
printf("3 - Excluir Contato \n");
printf("4 - Fechar Agenda \n");
scanf("%d", &opcaoMenu);
printf("\n A escolha do menu foi: %d \n\n", opcaoMenu);
switch (opcaoMenu) {
case 1:
adicionarContato(ptrAgenda);
break;
case 2:
listarContato(ptrAgenda);
break;
case 3:
// excluirContato("string");
printf("Excluiu o Contato! \n");
break;
case 4:
sairMenu++;
break;
default:
printf("Opção invalida, favor tentar novamente! \n");
break;
}
} while (sairMenu == 0);
}
return 0;
}
AGENDA *criarAgenda(char nome[30]) {
AGENDA *novaAgenda;
novaAgenda = (AGENDA *)malloc(sizeof(AGENDA));
strcpy(novaAgenda->nome, nome);
novaAgenda->listaContato = (CONTATO *)malloc(sizeof(CONTATO));
int tamContatos = (int)sizeof(novaAgenda[0].listaContato) /
(int)sizeof(novaAgenda[0].listaContato[0]);
return novaAgenda;
};
void adicionarContato(AGENDA *agenda) {
// DECLARANDO VARIAVEIS
char nomeContato[30], telContato[30], emailContato[30];
// ENTRADA DE DADOS
printf("Digite o nome do novo Contato! \n");
scanf("%29s", nomeContato);
printf("Digite o telefone do novo Contato! \n");
scanf("%29s", telContato);
printf("Digite o email do novo Contato! \n");
scanf("%29s", emailContato);
// PROCESSAMENTO
int tamListaContatos =
(int)sizeof(agenda[0].listaContato) /
(int)sizeof(agenda[0].listaContato[0]); // VERIFICANDO TAMANHO DA LISTA
if (agenda[0].listaContato[0].primeiro == NULL) {
// VERIFICA SE JA FOI CADASTRADO ALGUM CONTATO NA AGENDA
strcpy(agenda[0].listaContato[0].nome, nomeContato);
strcpy(agenda[0].listaContato[0].telefone, telContato);
strcpy(agenda[0].listaContato[0].email, emailContato);
agenda[0].listaContato[0].primeiro = &agenda[0].listaContato[0];
agenda[0].listaContato[0].ultimo = &agenda[0].listaContato[0];
printf("Contato adicionado com sucesso! \n");
} else {
// CASO JA TENHA ALGUM CONTATO ELE UTILIZA O REALOC
printf("\n\nCAIU NO REALLOC\n\n");
agenda[0].listaContato = (CONTATO *)realloc( agenda[0].listaContato, 1 + sizeof(agenda[0].listaContato[0]));
int tamListaContatos = (int) sizeof(agenda[0].listaContato) / (int)1 + (sizeof(agenda[0].listaContato[0]));
printf("\n\n%d\n\n", tamListaContatos);
strcpy(agenda[0].listaContato[tamListaContatos].nome, nomeContato);
strcpy(agenda[0].listaContato[tamListaContatos].telefone, telContato);
strcpy(agenda[0].listaContato[tamListaContatos].email, emailContato);
printf("Contato adicionado com sucesso! \n");
}
}
void listarContato(AGENDA *agenda) {
int tamListaContatos =
(int)sizeof(agenda[0].listaContato) / (int)sizeof(CONTATO);
for (int i = 0; i <= tamListaContatos; i++) {
printf("Contato id: %d \n", i);
printf("Contato nome: %s \n", agenda[0].listaContato[i].nome);
printf("Contato telefone: %s \n", agenda[0].listaContato[i].telefone);
printf("Contato email: %s \n", agenda[0].listaContato[i].email);
}
};