Tarefa 2 - Consultas médicas

Prazo de entrega:
Segunda chance:
Esta tarefa tem peso 1.

Você deve criar um pequeno sistema para gerenciar consultas médicas e precisará escolher tipos abstratos de dados adequados.


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 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. Homônimos e Parentes

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. Por dia, a clínica não atende mais do que 100 pacientes. As $n$ linhas seguintes contêm os nomes dos pacientes, separados por _ e com no máximo $30$ caracteres cada. A última linha contém a palavra homonimos seguida de um nome, ou a palavra parentes seguida de um sobrenome, indicando o que o usuário deseja fazer.

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

13
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
homonimos Manoel

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 Manoel, então a saída deverá ser:

Manoel_Araujo
Manoel_Carvalho

Se a opção selecionada tivesse sido parentes Barbosa, então a saída deveria ser:

Marcelo_Barbosa
Carlos_Barbosa

Em qualquer caso, os nomes devem aparecer na mesma ordem que foram dados na entrada.

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, que é no máximo 150. 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$, que é no máximo 50, 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 Jose_Borges S03 467665
registrar Adriana_Rocha A39 904319
registrar Luciana_Viera N70 839714
remover Jose_Borges
remover Adriana_Rocha
registrar Juliana_Castro E29 766602
fechar

Saída

Luciana_Viera atendido por Josefa_Cardoso: Salpingite e ooforite
Juliana_Castro atendido por Luciana_Carvalho: Disfuncao testicular

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 incorreta, o que provavelmente causou um erro depois. Leia os tutoriais disponibilizados.

Critérios

Deve haver um arquivo Makefile com pelo menos as regras para criar os executáveis classificar e consultas. Nas tarefas sempre será obrigatório utilizar pelo menos as flags -std=c99 -Wall -Werror -Wvla -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. Para ler o nome da doença, você pode usar outras funções ou especificações (veja as dicas acima). 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 estática para armazenar os dados de consultas, médicos e pacientes. Use tamanhos máximos que sejam apropriados para os vetores utilizados. Crie estruturas de dados para representar cada tipo de registro adequadamente.

Pense com calma, escreva seus algoritmos antes de programar e resolva os conjuntos de casos de teste mais simples primeiro.