Problem with fscanf

Asked

Viewed 467 times

-1

Good night! I have a question in my second fscanf on the part of PATIENTS, because I wanted to save the date that appears in the text file (the day in a->h.d_day, the month in a->h.d_mes and the year in a->h.d_ano), but I am showing random numbers on the console. Someone knows how to help me?

P.S.: On the part of doctors something was also supposed to appear, but I can’t find the error. If anyone knows, I’d also appreciate it.

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;
    };


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;
}

printf("\nMEDICOS\n");
while (fscanf(f,"%49[^\n] %49s %d:%d-%d:%d",v->nome, v->especialidade, &v->h_e.horas, &v->h_e.minutos, &v->h_s.horas, &v->h_s.minutos )==6 )
        printf("%s %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);

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",a->h.grau, &a->h.d_dia, &a->h.d_mes, &a->h.d_ano);
            printf("\t%s %d/%d/%d",a->h.grau, a->h.d_dia, a->h.d_mes, a->h.d_ano);
        }
fclose(f);
}

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

1 answer

0

The reading being done in the patient file does not correspond to the form with the data are arranged in the same.

In addition to the for is not inside the while because the { despite visually misleading by identation.

So this:

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",a->h.grau, &a->h.d_dia, &a->h.d_mes, &a->h.d_ano);
        printf("\t%s %d/%d/%d",a->h.grau, a->h.d_dia, a->h.d_mes, a->h.d_ano);
    }

To be properly identable it should be like this:

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",a->h.grau, &a->h.d_dia, &a->h.d_mes, &a->h.d_ano);
    printf("\t%s %d/%d/%d",a->h.grau, a->h.d_dia, a->h.d_mes, a->h.d_ano);
}

To fix the braces and the fscanfs should then stay like this:

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++)
    {
        //este fscanf ficou agora como %s - %d/%d/%d - %*[^\n]\n
        fscanf(g,"%s - %d/%d/%d - %*[^\n]\n",a->h.grau, &a->h.d_dia, &a->h.d_mes, &a->h.d_ano);
        printf("\t%s %d/%d/%d",a->h.grau, a->h.d_dia, a->h.d_mes, a->h.d_ano);
    }
}

Although already going through the correct data each history line, no for the h is to overlap the previously read line, and the same for the a referring the patient and superimposing the previous patient.

It will therefore be necessary to create structures, such as lists or arrays, that store the various lines of history and patients, in the right places.

Edit (referring to storing elements dynamically)

To save the elements, which comes in the file you need arrays or lists, and interestingly their structures paciente and medico are already lists!

If we look closely:

struct paciente
{
    ...
    p_pac prox; //typedef struct paciente pac, *p_pac;
};

In which p_pac is basically paciente* or be a pointer to the next paciente. And the same thing happens in the structure medico:

struct medico
{
    ...
    p_med prox;  //typedef struct medico med, *p_med;
};

We can start by creating two functions to show each of the lists following the sampling style you were using:

void imprimirMedicos(med *lista){
    while (lista != NULL){
        printf("%s %s %d %d %d %d\n",lista->nome, lista->especialidade, lista->h_e.horas,
               lista->h_e.minutos, lista->h_s.horas, lista->h_s.minutos);

        lista = lista->prox;
    }
}

void imprimirPacientes(pac *lista){
    while (lista != NULL){
        printf("\nNome: %s\nData de nascimento: %d-%d-%d\nConsultas: %d\n",lista->nome, lista->d_n.dia, lista->d_n.mes,
               lista->d_n.ano, lista->consultas);
        lista = lista->prox;
    }
}

With some corrections as it had printfs using the variable address (&) which is not supposed, for example here:

while (fscanf(f, ...) == 6 )
    printf("%s %s %d %d %d %d\n" ..., &v->h_e.horas, &v->h_e.minutos, ...);

Now every time you read it, you can build the list forward. I tried to use a simple way to build the list that means that it doesn’t change much what you have and so it doesn’t mean it’s the best implementation. But it would be something like:

int le_dados ()
{
    FILE *f, *g;

    med *v = malloc (sizeof(med));
    pac *a = malloc (sizeof(pac));

    ... //abertura dos ficheiros e ifs que estavam aqui antes

    printf("\nMEDICOS\n");
    med *listaMedicos = v; //dizer que a lista começa no v, o primeiro médico
    med *anterior = NULL; 

    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)); //alocar um Nó para o próximo médico
        anterior = v; //ponteiro para o médico antes do fim
        v = v->prox;
    }

    if (anterior == NULL){ //não deu para ler nenhum médico libertar o único nó alocado
        free(listaMedicos);
        listaMedicos = NULL;//por a único apontar para NULL a impressão funcionar 
    }
    else {
        free(anterior->prox);//libertar o ultimo médico alocado que não foi utilizado
        anterior->prox = NULL;//por a ultimo apontar para NULL a impressão funcionar 
    }

    imprimirMedicos(listaMedicos);


    pac *listaPacientes = a; //dizer que 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) {

        for(i=0; i<a->consultas; i++)
        {
            //agora com * para ignorar e ler sem colocar em lado nenhum
            fscanf(g,"%*s - %*d/%*d/%*d - %*[^\n]\n");
        }

        a->prox = malloc(sizeof(pac)); //alocar um Nó para o próximo paciente
        antPac = a; //ponteiro para o 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 único apontar para NULL a impressão funcionar 
    }
    else {
        free(antPac->prox); //libertar o ultimo paciente alocado que não foi utilizado
        antPac->prox = NULL;//por a ultimo apontar para NULL a impressão funcionar 
    }

    imprimirPacientes(listaPacientes);
}

It leaves purposely to implement the historical part in order to exercise its programming techniques. However, I would remind you that the historical structure is not yet ready to function as a list.

  • Thank you so much, it’s working! At the moment only the information is showing for a patient, I have to do a go to show all of the file?

  • @Joanasantos already put one \n which was missing. The way it is it already goes through all the information in the file. However, each one needs to be stored in a different place.

  • I’m sorry... but do you know how I can do that? ...

  • @Joanasantos I edited my answer to contemplate the storage of information

  • Thank you very much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.