How to look for an element in a vector of structures?

2

Good evening! I am doing a job in 'C' where I have to look for doctors by specialty, that is, I ask the user the name of the specialty to look for and I make a'printf 'of the doctors of that specialty. I tried to do this but always gives me "Enixestente Specialty." even looking for a specialty that I know is in the file.

Can someone help me?

So far my code is this:

struct hora_entrada{int horas, minutos;};

struct hora_saida{int horas, minutos;};

typedef struct medico med, *p_med;
struct medico{
    char nome[ST_TAM];
    char especialidade[ST_TAM];
    struct hora_entrada h_e;
    struct hora_saida h_s;
    p_med prox;
};

struct data_nasc{int dia, mes, ano;};

struct historico{
    char grau[ST_TAM];
    int d_dia;
    int d_mes;
    int d_ano;
    char nome[ST_TAM];
};

typedef struct paciente pac, *p_pac;
struct paciente{
    char nome[ST_TAM];
    struct data_nasc d_n;
    int consultas;
    struct historico h;
    p_pac prox;
};


//Listagem completa de medicos e pacientes

 int le_dados (){
    FILE *f, *g;
    med *v;
    pac *a;
    int i;
    f=fopen("medico.txt", "rt");
    g=fopen("paciente.txt", "rt");
    if (f==NULL || g==NULL){
        printf("Erro no acesso ao ficheiro.\n");
        return 0;
    }
v=malloc(sizeof(med));
a=malloc(sizeof(pac));
if (v==NULL || a==NULL){
    printf("Erro na alocaçao de memoria.\n");
    return 0;
}

med *listaMedicos = v; //a lista começa no v, o primeiro médico
med *antMed = NULL;
printf("\nMEDICOS\n");
while (fscanf(f,"%49[^\n] %49s %d.%d - %d.%d\n",v->nome, v->especialidade, &v->h_e.horas, &v->h_e.minutos, &v->h_s.horas, &v->h_s.minutos )==6 ){
        printf("%s\n%s %d.%d %d.%d\n",v->nome, v->especialidade, v->h_e.horas, v->h_e.minutos, v->h_s.horas, v->h_s.minutos);
        v->prox = malloc(sizeof(med)); //aloca um nó para o próximo médico
        antMed = v; //ponteiro para o médico antes do fim
        v=v->prox;
}
if (antMed == NULL){ //não deu para ler nenhum médico, libertar o único nó alocado
    free(listaMedicos);
    listaMedicos = NULL; //por o a apontar para NULL para a impressão funcionar
}
else{
    free(antMed->prox); //libertar o último médico alocado que não foi utilizado
    antMed->prox = NULL; //por a apontar para NULL para a impressão funcionar
}


pac *listaPacientes = a; //a lista começa no a, o primeiro paciente
pac *antPac = NULL;
printf("\n\nPACIENTES\n");
while (fscanf(g,"%49[^\n] %d-%d-%d %d",a->nome, &a->d_n.dia, &a->d_n.mes, &a->d_n.ano, &a->consultas)==5){
        printf("Nome: %s\nData de nascimento: %d-%d-%d\nConsultas: %d\n",a->nome, a->d_n.dia, a->d_n.mes, a->d_n.ano, a->consultas);
        for(i=0;i<a->consultas;i++){
            fscanf(g,"%s - %d/%d/%d - %[^\n]\n",a->h.grau, &a->h.d_dia, &a->h.d_mes, &a->h.d_ano, &a->h.nome);
            printf("\t%s %d/%d/%d %s\n",a->h.grau, a->h.d_dia, a->h.d_mes, a->h.d_ano, a->h.nome);
        }
        a->prox = malloc(sizeof(pac)); //alocar um nó para o próximo paciente
        antPac = a; //ponteiro para o paciente antes do fim
        a = a->prox;
}
if (antPac == NULL){ //não deu para ler nenhum paciente, libertar o único nó alocado
    free(listaPacientes);
    listaPacientes = NULL; //por a apontar para NULL para a impressão funcionar
}
else{
    free(antPac->prox); //libertar o ultimo paciente alocado que não foi utilizado
    antPac->prox = NULL; //por a apontar para NULL para a impressão funcionar
}

fclose(f);
}


//Pesquisar médicos por especialidade

int pesquisa (p_med v){
    char esp;
    printf("Insira uma especialidade a pesquisar:\n");
    scanf("%s", &esp);
    while (v!=NULL && v->especialidade!=esp)
        v=v->prox;
    if (v!=NULL)
        printf("%s\n",v->nome);
    else
        printf("Especialidade enixestente.\n");

}

int menu() {
    int op;
    printf("\n1 - Listagem completa de medicos e pacientes");
    printf("\n2 - Pesquisar medicos por especialidade");
    do {
        printf("\nEscolha uma opcao: ");
        scanf("%d", &op);
    } while (op < 1 || op > 2);
    return op;
}

int main(int argc, char *argv[]) {
    int i;
    // Ponteiro de lista
    med *v;
    p_med lista = v;
    do {
        i = menu();
        switch (i) {
            case 1: le_dados();
                break;
            case 2: pesquisa(lista);
                break;
        }
    } while (i != 2);
    return 0;
}
    
asked by anonymous 22.08.2017 / 00:00

1 answer

1

I tried to change your code by keeping as much fidelity to what you did, when possible just by switching things around. (Tested on Debian 9 with GCC 6.3.0)

Summary of changes

  • I had to move all the opening and reading part of the files, so such as the allocation of structures, to the main;
  • I separated main into sections, each section with its own error handling;
  • The data is loaded into memory before use now, as it was, if you clicked on 2 first there would be no list;
  • I put the release of the memory and the closing of the files at the end;
  • I created two functions to replace le_dates (), medical_list () and patient_list (). It seemed more appropriate.

Corrected code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ST_TAM 50

struct data_nasc{int dia, mes, ano;};
struct horario{int horas, minutos;};

typedef struct medico med, *p_med;
struct medico{
    char nome[ST_TAM];
    char especialidade[ST_TAM];
    struct horario h_e;
    struct horario h_s;
    p_med prox;
};

struct historico{
    char grau[ST_TAM];
    int d_dia;
    int d_mes;
    int d_ano;
    char nome[ST_TAM];
};

typedef struct paciente pac, *p_pac;
struct paciente{
    char nome[ST_TAM];
    struct data_nasc d_n;
    int consultas;
    struct historico h;
    p_pac prox;
};

//Pesquisar médicos por especialidade
int pesquisa (p_med v){
    int result = 0;
    char esp[ST_TAM]; // Aqui deveria ser um array, certo?
    printf("Insira uma especialidade a pesquisar:\n");
    scanf("%s", esp);

    if(v != NULL){
        while (v != NULL){
            if (strcmp(esp,v->especialidade) == 0){
                printf("%s\n",v->nome);
                result++;
            }
            v = v->prox;
        }

        // Se nenhum foi encontrado
        if(result == 0){
            printf("Especialidade inexistente.\n");
            return 1;
        }
    }else{
        printf("Lista vazia\n");
        return 1;
    }
    return 0;
}

int menu() {
    int op;
    printf("\n1 - Listagem completa de medicos e pacientes");
    printf("\n2 - Pesquisar medicos por especialidade");

    do {
        printf("\nEscolha uma opcao: ");
        scanf("%d", &op);
    } while (op < 1 || op > 2);
    return op;
}

int listar_medicos(p_med v){
    printf("\nLista de medicos:\n");
    if(v != NULL){
        while (v->prox != NULL){
            printf("%s\n%s %d.%d %d.%d\n",v->nome, v->especialidade, v->h_e.horas, v->h_e.minutos, v->h_s.horas, v->h_s.minutos);
            v = v->prox;
        }
    }else{
        printf("Lista vazia\n");
        return 1;
    }

    return 0;
}

int listar_pacientes(p_pac a){
    printf("\nLista de pacientes:\n");
    if(a != NULL){
        while (a->prox != NULL){
            printf("Nome: %s\nData de nascimento: %d-%d-%d\nConsultas: %d\n",a->nome, a->d_n.dia, a->d_n.mes, a->d_n.ano, a->consultas);
            a = a->prox;
        }
    }else{
        printf("Lista vazia\n");
        return 1;
    }
    return 0;
}

int main(int argc, char *argv[]) {
    int i;
    FILE *f, *g;
    med *v;
    pac *a;

    // Alocação de memória  
    v=malloc(sizeof(med));
    a=malloc(sizeof(pac));

    if (v==NULL || a==NULL){
        printf("Erro na alocaçao de memoria.\n");
        exit(1);
    }

    // Listagem de médicos
    med *listaMedicos = v; //a lista começa no v, o primeiro médico
    med *antMed = NULL;
    f=fopen("medico.txt", "rt");

    if (f==NULL){
        printf("Nao foi possivel abrir o arquivo medico.txt.\n");
        exit(1);
    }else{
        printf("\nCarregando listagem de medicos ...\n");
        while (fscanf(f,"%49[^\n] %49s %d.%d - %d.%d\n",v->nome, v->especialidade, &v->h_e.horas, &v->h_e.minutos, &v->h_s.horas, &v->h_s.minutos )== 6 ){
            v->prox = malloc(sizeof(med)); //aloca um nó para o próximo médico
            antMed = v; //ponteiro para o médico antes do fim
            v=v->prox;
        }
    }

    // Listagem de pacientes
    pac *listaPacientes = a; //a lista começa no a, o primeiro paciente
    pac *antPac = NULL;
    g=fopen("paciente.txt", "rt");

    if (g==NULL){
        printf("Nao foi possivel abrir o arquivo paciente.txt\n");
        exit(1);
    }else{
        printf("Carregando listagem de pacientes ...\n");
        while (fscanf(g,"%49[^\n] %d-%d-%d %d",a->nome, &a->d_n.dia, &a->d_n.mes, &a->d_n.ano, &a->consultas)==5){
            for(i=0;i<a->consultas;i++){
                fscanf(g,"%s - %d/%d/%d - %[^\n]\n",a->h.grau, &a->h.d_dia, &a->h.d_mes, &a->h.d_ano, a->h.nome);
            }
            a->prox = malloc(sizeof(pac)); //alocar um nó para o próximo paciente
            antPac = a; //ponteiro para o paciente antes do fim
            a = a->prox;
        }
    }

    // Loop principal
    do {
        i = menu();
        switch (i) {
            case 1: 
                listar_medicos(listaMedicos);
                listar_pacientes(listaPacientes);
                break;
            case 2: pesquisa(listaMedicos);
                break;
        }
    }while (i != 0);

    // Liberação da memória e fechamento dos arquivos
    fclose(f);
    fclose(g);
    free(v);
    free(a);
    return 0;
}

Running

Suggestions

  • Include in your menu an option to exit;
  • Put meaningful names in your variables, over time we can forget what they are for.

Hope this helps.

    
25.08.2017 / 22:41