Tarefa 2 - Gerenciamento de consultas médicas

Prazo de entrega recomendado:

Você deve criar um pequeno sistema para gerenciar consultas médicas e precisará escolher tipos abstratos de dados adequados e realizar alocação dinâmica.


Uma clínica médica manipula diariamente informações sobre doenças, médicos, pacientes e consultas médicas. Diante da grande quantidade de dados, os funcionários têm dificuldades para gerenciá-los.

Cada doença é representada pelo código CID (Classificação Internacional de Doenças) e pelo nome da doença. Os dados dos médicos incluem o nome e o número do CRM (Conselho Regional de Medicina). Além disso, a clínica gerencia informações sobre consultas médicas realizadas. Cada consulta agrupa diversas informações, incluindo o paciente e o médico correspondentes e, possivelmente, um diagnóstico.

O gerente da clínica gostaria de visualizar um relatório com a lista das últimas consultas de cada paciente. Ele gostaria de listar essas consultas ordenadas alfabeticamente pelo nome ou pelo sobrenome. Você foi contratado para criar uma gerenciador de consultas que facilite o manuseio dessas informações, permitindo a inserção, remoção e alteração de dados.

1. Ordenação dos nomes

Para evitar confusão entre as pessoas sendo chamadas, é importante identificar os pacientes com nomes homônimos. Por exemplo, Antonio Silva e Antonio Pereira são homônimos. Além disso, é importante descobrir quais pacientes são da mesma família. São considerados da mesma família aqueles que têm o mesmo último sobrenome. Por exemplo, Maria Santos e Luiz Santos são parentes.

Na primeira fase do projeto, você precisará escrever um programa classificar que recebe uma lista de nomes de pacientes e identifica aqueles que são homônimos ou parentes.

Entrada

A primeira linha contém um inteiro $n$ indicando o número de pacientes. A segunda linha contém uma palavra homonimos ou parentes indicando o que o usuário deseja fazer. As $n$ linhas seguintes contêm os nomes dos pacientes, separados por _ e com no máximo $30$ caracteres cada.

Cada paciente tem um nome e um sobrenome, por exemplo Luiz_Silva, você não encontrará casos como Luiz_da_Silva.

13
homonimos
Luiz_Silva
Sandra_Lima
Paulo_Pereira
Francisca_Borges
Marcelo_Barbosa
Manoel_Araujo
Geraldo_Ramos
Carlos_Barbosa
Luis_Costa
Francisca_Cardoso
Juliana_Santana
Ada_Ramos
Manoel_Carvalho

Saída

A saída consiste da lista dos nomes de pacientes que são homônimos ou parentes, a depender da opção selecionada.

Quando a opção selecionada for homonimos, então a saída deverá ser ordenada lexicograficamente.

Francisca_Borges
Francisca_Cardoso
Manoel_Araujo
Manoel_Carvalho

Se a opção selecionada tivesse sido parentes, então a saída deveria ser ordenada por sobrenome e, em seguida, lexicograficamente.

Carlos_Barbosa
Marcelo_Barbosa
Ada_Ramos
Geraldo_Ramos

2. Gerenciamento das consultas

A clínica mantém um arquivo de texto dados/doencas.txt com os dados de todas as doenças. Esse arquivo contém um número na primeira linha com o número $n$ de doenças registradas. Cada uma das $n$ linhas seguintes contém um código CID (uma letra maiúscula e um número de dois dígitos) e o nome da doença (com até 100 caracteres incluindo espaços).

Além disso, ela mantém um arquivo de texto dados/medicos.txt com os dados dos médicos. A primeira linha contém o número de médicos $n$ e cada uma das $n$ linhas seguintes contém os dados de um médico, incluindo o número do CRM (um número de no máximo 6 dígitos) e o nome do médico (veja o arquivo).

Todo dia, a secretária precisa registrar as consultas dos pacientes atendidos naquele dia. Para ajudá-la, você irá criar um programa interativo chamado consultas que responde a uma série de comandos. Cada comando é uma string, possivelmente seguida de parâmetros.

Entrada

abrir 6
registrar Josefa_Almeida F10 609886
registrar Jose_Alves A23 641969
remover Josefa_Almeida
remover Jose_Alves
registrar Antonio_Silva C00 981622
registrar Jose_Soares K26 293623
fechar

Saída

Antonio_Silva atendido por Rosa_Silva: Neoplasia maligna do labio
Jose_Soares atendido por Vera_Soares: ulcera duodenal

Dicas

Para abrir um arquivo em C, você deve usar um ponteiro para o tipo FILE e as operações associadas fopen e fclose. A leitura é feita com fscanf, que opera da mesma maneira que scanf, mas lê do arquivo aberto passado. Veja um exemplo que lê uma matriz de caracteres separados por espaço.

int main() {
    char matriz[MAX][MAX];
    int m, n;
    FILE *fp = fopen("caca-palavras.txt", "r");
    if (fp == NULL) {
        perror("Não foi possível abrir caca-palavras.txt");
        return 1;
    }
    fscanf(fp, "%d%d", &m, &n);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            fscanf(fp, " %c", &matriz[i][j]);
        }
    }
    fclose(fp);
}

O formato %s do scanf serve para ler uma string sem espaços. Às vezes é necessário ler uma string que pode incluir espaços. Há várias maneiras de fazer isso, por exemplo, utilize scanf(" %[^\n]", buffer) para ler uma string até o final da linha. Repare que há um espaço antes de forma que os espaços no início serão ignorados. Muito cuidado: sempre que ler uma string, pergunte-se se o buffer tem espaço disponível para a maior string possível mais o caractere nulo.

Mesmo com muito cuidado, quando trabalhamos em C, muitas vezes acabamos tendo problemas de acesso e memória muito difíceis de encontrar. A reação natural de muitos estudantes é tentar modificar os programas, inserindo printfs cegamente nas mais diversas posições. Nunca faça isso. Nunca faça isso. Nunca faça isso! Execute seu programa primeiro com o gdb e depois com o valgrind. Na maioria das vezes, o gdb irá informar em qual linha ocorreu uma falha de segmentação e o valgrind irá informar em que linha acessamos a memória de maneira , que provavelmente causou o erro depois. Leia os tutoriais disponibilizados.

Critérios

Deve haver um arquivo Makefile com pelo menos as regras que para criar os executáveis classificar e consultas. Nas tarefas sempre será obrigatório utilizar pelo menos as flags -std=c99 -Wall -Werror -Werror=vla -g do compilador. Se quiser e achar conveniente, você pode dividir o seu código-fonte em vários arquivos e utilizar e adaptar o Makefile para compilá-los separadamente.

Para ler um nome completo de um paciente ou de um médico, utilize a função scanf passando obrigatoriamente a especificação de formato %s. Se desejar, você pode utilizar as funções strlen, strcpy e strcmp da biblioteca <string.h>; outras funções são proibidas.

É obrigatório usar alocação dinâmica para armazenar os dados de consultas, médicos e pacientes. Crie estruturas de dados para representar cada tipo de registro adequadamente.

Pense com calma, escreva seus algoritmos antes de programar e resolva os conjuntos com casos de teste mais simples primeiro. Para obter conceito C, não é necessário identificar parentes.

Correção

Esta tarefa será corrigida automaticamente sempre que você realizar um git push. Depois de submetida a versão final da tarefa, você deverá apresentá-la a um monitor PED. Para isso, você deve procurar atendimento em algum horário com monitor PED e digitar apresentar 2 no canal fila-apresentar para entrar na fila.