Criando uma agenda em C

Oi gente! Gostaria da ajuda de vocês para fazer um trabalho(não quero o código, só uma orientação, porque tô bem perdida).

Descrição do Trabalho
Faça um programa que controle uma agenda. O usuario deve poder:
• Inserir um contato na agenda. Cada contato deve ter, pelo menos: nome, telefone, endereco, cidade,
estado e data de nascimento.
• Consultar todos os contatos da agenda.
• Pesquisar os contatos por nome.
• Modificar as informacoes de um contato.
Requisitos:
• O numero maximo de contatos que agenda deve armazenar e 100.
Nao pode haver desperdıcio de espaco ao armazenar nome, endereco e cidade. Ou seja, esse campos
devem ter seus tamanhos calculados e alocados dinamicamente usando ponteiros e malloc.
• Obrigatorio o uso de registros (struct) para organizar a informacao.
• Altamente recomendado o uso de funcoes.

2 curtidas

Precisa construir de código na minha visão:

1 - Um classe modelo que servirá de base tendo os dados de contato

class Contato {
    private String nome;
   ...
   // e os seus get/set
}

2 - Um lista da classe modelo, já visto que para guardar e simular um banco de dados em memória precisa de uma lista de modelo. (no caso parece ser uma lista com array fixo com 100 posições:

Contato[] contatos = new Contato[100]; // array com 100 posições
int index = 0; // essa variável para controlar qual é o próximo a ser inserido

Comece por isso depois vai surgir a duvida de busca

Isso seria uma base: a outra coisa é criar um menu de opções

Há isso é fosse feito em Java! é uma ideia.

1 curtida

Em C ou C++?

O colega deu um exemplo usando C++.

1 curtida

Em C

Qual é a sua dúvida exatamente? O exercício já indica o que tu deve usar para montar a agenda. Deve haver uma função que gerará o menu que irá perguntando ao usuário qual ação pretende tomar… “Deseja incluir um contato ? [S/N]”; "Deseja alterar um conato?[S/N], etc.

1 - Use uma struct para definir os dados do contato/pessoa;
2 - Use alocação de memória (usando malloc) para definir o nome, o endereço e cidade;
3 - Use funções para cada operação da agenda. Uma dedicada à inserção, outra à alteração, etc.

1 curtida

Eu não testei todos os métodos, é mais para te dar um norte:

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

#define MAX 100

struct Pessoa{
    char* nome;
    int idade;
    char telefone[17];
    char* endereco;
    char* cidade;
    char estado[2];
}pessoa[MAX];

void exibirMenu(){
    printf("\n\tSelecione umas das opções a seguir:\n");
    printf("\t01 - Inserir contato\n"
           "\t02 - Listar contatos\n"
           "\t03 - Pesquisar contato\n"
           "\t04 - Alterar contato\n"
           "\t99 - Sair\n\n");
}

char* alocarMemoria(int tamanho){
    char* info = NULL;
    info = (char*) malloc(sizeof(tamanho) * sizeof(char));

    if(info == NULL){
        printf("ERRO: impossível alocar a quantidade de memória requisitada!");
        exit(1);
    }
    return info;
}

void cadastrarContato(int registro){
    char dados[MAX];
    printf("\n\t\tNome: ");
    scanf("%[^\n]s", dados);
    setbuf(stdin, NULL);
    //Alocação e cópia de dados
    pessoa[registro].nome = alocarMemoria(strlen(dados));
    strcpy(pessoa[registro].nome, dados);

    printf("\t\tIdade: ");
    scanf("%d", &pessoa[registro].idade);
    setbuf(stdin, NULL);

    printf("\t\tTelefone: ");
    scanf("%[^\n]s", pessoa[registro].telefone);
    setbuf(stdin, NULL);

    printf("\t\tEndereço: ");
    scanf("%[^\n]s", dados);
    setbuf(stdin, NULL);
    //Alocação e cópia de dados
    pessoa[registro].endereco = alocarMemoria(strlen(dados));
    strcpy(pessoa[registro].endereco, dados);

    printf("\t\tCidade: ");
    scanf("%[^\n]s", dados);
    setbuf(stdin, NULL);
    //Alocação e cópia de dados
    pessoa[registro].cidade = alocarMemoria(strlen(dados));
    strcpy(pessoa[registro].cidade, dados);

    printf("\t\tEstado: ");
    scanf("%[^\n]s", pessoa[registro].estado);
    setbuf(stdin, NULL);
}

void listarContatos(int qtdeContatos){
    int i;
    int contagem = 1;
    for(i = 0; i < qtdeContatos; i++){
        printf("\n\tContato nº: %d\n", contagem++);
        printf("\tNome: %s\n", pessoa[i].nome);
        printf("\tIdade: %d\n", pessoa[i].idade);
        printf("\tTelefone: %s\n", pessoa[i].telefone);
        printf("\tEndereço: %s\n", pessoa[i].endereco);
        printf("\tCidade: %s-%s\n", pessoa[i].cidade, pessoa[i].estado);
    }
    printf("\n\n");
}

void exibirContato(int indice){
    printf("\n\tNome: %s\n", pessoa[indice].nome);
    printf("\tIdade: %d\n", pessoa[indice].idade);
    printf("\tTelefone: %s\n", pessoa[indice].telefone);
    printf("\tEndereço: %s\n", pessoa[indice].endereco);
    printf("\tCidade: %s-%s\n\n", pessoa[indice].cidade, pessoa[indice].estado);
}

int pesquisarContato(int qtdeContatos, char* nomeBuscado){
    int i;

    for(i = 0; i < qtdeContatos; i++){
        if(strcmp(nomeBuscado, pessoa[i].nome) == 0)
            return i;
    }
    return -1;
}

void atualizarContato(int indice){
    char* nome;
    int idade;
    char fone[16];
    char* endereco;
    char* cidade;
    char uf[2];

    char dados[MAX];
    printf("\n\t\tNome: ");
    scanf("%[^\n]s", dados);
    setbuf(stdin, NULL);
    //Alocação e cópia de dados
    nome = alocarMemoria(strlen(dados));
    strcpy(nome, dados);

    printf("\t\tIdade: ");
    scanf("%d", &idade);
    setbuf(stdin, NULL);

    printf("\t\tTelefone: ");
    scanf("%[^\n]s", fone);
    setbuf(stdin, NULL);

    printf("\t\tEndereço: ");
    scanf("%[^\n]s", dados);
    setbuf(stdin, NULL);
    //Alocação e cópia de dados
    endereco = alocarMemoria(strlen(dados));
    strcpy(endereco, dados);

    printf("\t\tCidade: ");
    scanf("%[^\n]s", dados);
    setbuf(stdin, NULL);
    //Alocação e cópia de dados
    cidade = alocarMemoria(strlen(dados));
    strcpy(cidade, dados);

    printf("\t\tEstado: ");
    scanf("%[^\n]s", uf);
    setbuf(stdin, NULL);

    pessoa[indice].nome = nome;
    pessoa[indice].idade = idade;
    strcpy(pessoa[indice].telefone, fone);
    pessoa[indice].endereco = endereco;
    pessoa[indice].cidade = cidade;
    strcpy(pessoa[indice].estado, uf);
}

int leitor(){
    int opcao;

    printf("\n\tOpção escolhida: ");
    scanf("%d", &opcao);
    setbuf(stdin, NULL);

    return opcao;
}

int main(){
    char nome[MAX];
    int numeroRegistro = 0;
    int opcaoEscolhida;
    int indice;

    do{
        exibirMenu();
        opcaoEscolhida = leitor();

        switch(opcaoEscolhida){
            case 1:
                cadastrarContato(numeroRegistro++);
                break;
            case 2:
                listarContatos(numeroRegistro);
                break;
            case 3:
                printf("\n\tNome: ");
                scanf("%[^\n]s", nome);
                indice = pesquisarContato(numeroRegistro, nome);

                if(indice >= 0 && indice <= 99)
                    exibirContato(indice);
                else
                    printf("\n\tContato não cadastrado!");
                break;
            case 4:
                printf("\n\tContato número [1 - 99]: ");
                scanf("%d", &indice);
                indice -= 1;
                if(indice >= 0 && indice <= 99)
                    atualizarContato(indice);
                else
                    printf("\n\tContato inválido!");
                break;
            case 99:
                printf("\n\tSaindo...");
                break;
            default:
                printf("Opção inválida!");
                exibirMenu();
                opcaoEscolhida = leitor();
        }

    }while(opcaoEscolhida != 99);
}
1 curtida

Pegando carona na dúvida da colega
O comando abaixo permite ignorar o <enter> com o uso de expressão regular?

Você saberia a forma mais correta de limpar a tela? No Linux/MacOs seria via “clear” e no Windows “cls”. No C tenho que imprimir uma sequência de linhas em branco até cobrir a tela?

#define LINHAS 80
int linha;
for ( linha = 0; linha < LINHAS; linha++ )
printf("\n");

…ou existe algum atalho para chamar o comando?

exec(“clear”); ou system(“clear”);

1 curtida

Sobre o scanf:

1 - [...]: define que será lido uma sequência de valores ignorando espaços (não ‘tokeniza’) pelo aparecimento de espaço;
2 - [^\n]: define que a sequência termina quando encontrar um enter (‘tokeniza’ quando encontra um enter).

Na verdade, no caso da variável uf que lê a sigla do estado nem precisaria usar o scanf com a expressão regular, mas eu acabei fazendo tudo igual. Eu não usei o fgets porque ele tem o parâmetro length e, como o exercício pede alocação dinâmica, não faz sentido eu passar o tamanho da string.

Fonte 1: Programar em C/Entrada e saída simples.

Fonte 2: Lendo string com espaços na função scanf() - Linguagem C.

Sobre a limpeza do console, existe a função clrscr(); da conio.h. Sugiro esse post: How to clear console in C?.

2 curtidas

muito obrigado! vou estudar seu código

O que isso faz?

Limpa o buffer de entrada padrão:

1 - stdin: standard input (entrada padrão, ou seja o teclado)
2 - NULL: Indica que não haverá ‘bufferização’.

Para mais detalhes, consulte aqui: setbuf.

e aqui: Aula 81 – Limpar o Buffer do teclado.

Sugestão: melhor portal de linguagem C que eu conheço (Ensino de C e de ED em C): Linguagem C Descomplicada.

1 curtida

Muito obrigada e mais uma dúvida
Eu entendi qual é a função de scanf("%[^\n]s", uf), acontece que quando vou usar ela, ela não funciona. Aparece a opção que a pessoa escolheu e já chama o menu novamente, sem a pessoa conseguir digitar primeiro.
Aqui uma parte do código:

void upgradeContact(int index){
	char* name;
	int age;
	char cellnumber[16];
	char* adress;
	char* city;
	char state[2];
	
	char data[MAX];
	int op;

	printf("\tO que deseja atualizar?");
	printf("\n\t[1] - Nome\n"
	"\t[2] - Idade\n"
	"\t[3] - Celular\n"
	"\t[4] - Endereço\n"
	"\t[5] - Cidade\n"
	"\t[6] - Estado\n"
	"\t[7] - Tudo\n"
	"\t[0] - Voltar\n");
	printf("\n\tOpção escolhida: ");
	scanf("%i", &op);
	
	switch(op){
		case 1:
			printf("\n\t\tNome: ");
			scanf("%[^\n]s", data);
			setbuf(stdin, NULL);
			//Alocação e cópia de dados
			name = memoryAllocation(strlen(data));
			strcpy(name, data);
			contact[index].name = name;
			break;

Faltou limpar o buffer depois de ler a opção:

O certo seria:

scanf("%d", &op);
setbuf(stdin, NULL);

como eu fiz aqui:

int leitor(){
    int opcao;

    printf("\n\tOpção escolhida: ");
    scanf("%d", &opcao);
    setbuf(stdin, NULL);

    return opcao;
}
1 curtida

Tá bem, muito obrigada! Tu ajudou muito :wink: