Printing the records of a file

Asked

Viewed 43 times

0

I am making a program in c, which will read the records of a file and pass the name contained in the records to a double-chained list where they will be sorted alphabetically, and then with the help of the list the records of the file will be printed in order.

That is the code:

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


typedef struct registro{
char matricula[5];
char nome[50];
char genero;
float salario;
char cargo;
char setor[2];
}registro;

typedef struct tiplista{
struct elem *inicio;
struct elem *fim;
}tiplista;

typedef struct elem{
char nome[50];
struct elem *ant;
struct elem *prox;
int pos; // posição do elemento no arquivo binário
}elem;

void insercao_lista_ordenada(tiplista *lista, char nome[50], int posicao){
    elem *aux;
    elem *novoelemento=(elem*)malloc(sizeof(elem));
    strcpy(novoelemento->nome,nome);
    novoelemento->prox= NULL;
    novoelemento->ant= NULL;
    novoelemento->pos=posicao;
    if(lista->inicio == NULL){ //lista vazia

        lista->inicio=novoelemento;
        lista->fim=novoelemento;

    }else{

        aux = lista->inicio; // pont aux recebe o ponteiro do início da lista
        while ((aux->prox != NULL) && (strcmp(aux->nome, nome) < 0))
        {
            aux = aux->prox;

        }
        // verificar se a inserção no início
        if ((aux == lista->inicio) && ((strcmp(aux->nome, nome)) > 0))
        {

            novoelemento->prox = lista->inicio;
            lista->inicio->ant = novoelemento;
            lista->inicio = novoelemento;

        }
        else if ((strcmp(aux->nome, nome)) < 0) // elemento a ser inserido maior
            {

                // verificar se a inserção no final
                if (aux == lista->fim)
                {
                    novoelemento->ant = lista->fim;
                    lista->fim->prox = novoelemento;
                    lista->fim = novoelemento;

                }
                else // inserção no meio
                {
                    novoelemento->ant = aux->ant;
                    aux->ant->prox = novoelemento;
                    novoelemento->prox = aux;
                    aux->ant = novoelemento;

                }
            }

    }

return;
}

void imprimir_lista(tiplista *lista)
{
    elem *aux;
    registro reg;
    FILE *arq_bin_p;
    if((arq_bin_p=fopen("arq_bin_principal.bin","rb")) == NULL){
        printf("Erro: não foi possível encontrar o arquivo.");
        system("pause");
        exit(1);
    }

    aux = lista->inicio;
    while (aux != NULL) // percorre a lista
    {
        // posiciona o ponteiro do arquivo na posição do registro
        fseek (arq_bin_p, aux->pos * sizeof(registro), SEEK_SET);
        // faz a leitura do registro na posição
        fread(&reg, sizeof(registro),1 , arq_bin_p);
        printf("%s \n",reg.matricula);
        printf("%s \n",reg.nome);
        printf("%c \n",reg.genero);
        printf("%f \n",reg.salario);
        printf("%c \n",reg.cargo);
        printf("%s \n\n",reg.setor);

        aux = aux->prox; // avança para o próximo elemento da lista
    }
}

int main(){

    registro p[6],reg;
    tiplista *lista=(tiplista*)malloc(sizeof(tiplista));
    int pos=0;
    lista->inicio=NULL;
    lista->fim=NULL;

    p[0]=(const registro){"15101","Carlos",'M',2500.00,'A',"02"};
    p[1]=(const registro){"11256", "Ana", 'F', 1850.00, 'E', "01"};
    p[2]=(const registro){"11436", "Roberto", 'M', 1550.00, 'A', "51"};
    p[3]=(const registro){"11354", "José", 'M' ,1350.00, 'D', "04"};
    p[4]=(const registro){"12542", "Elaine", 'F', 2750.00, 'B', "22"};
    p[5]=(const registro){"00812", "Murilo", 'M', 3500.00, 'E', "01"};

    FILE *arq_bin_p=fopen("arq_bin_principal.bin","wb");
    fwrite(p, sizeof(registro),6,arq_bin_p);

    fclose(arq_bin_p);

    if((arq_bin_p=fopen("arq_bin_principal.bin","rb")) == NULL){
        printf("Erro: não foi possível encontrar o arquivo.");
        system("pause");
        exit(1);
    }

    while(fread(&reg,sizeof(registro),1,arq_bin_p)){

        insercao_lista_ordenada(lista,reg.nome,pos);
        pos++;
    }
    fclose(arq_bin_p);
    imprimir_lista(lista);


system("pause");
return 0;
}

The problem is that when compiling this program it only prints 3 of the 6 records of the file, and somehow "reg.matricula" this storing the matricula and the name together. What I am missing?

1 answer

1


Good night.

reg.matricula keeping the license plate and the name together

reg.matricula not holding the license plate and the name together. reg.matricula is being treated as a string, so far so good, the problem is that it does not have the \0 to indicate its end. Note:

// Matricula tem 5 posições
char matricula[5];

// Então você atribui uma matricula para o Carlos
p[0]=(const registro){"15101","Carlos",'M',2500.00,'A',"02"};

When we use double quotes to assign something to a vector of characters the \0 is at the end, but as 15101 has the size of the vector so the \0 will be left out in the registration position[5].

matricula[0] = '1'

registration[1] = '5'

matricula[2] = '1'

matricula[3] = '0'

matricula[4] = '1'

matricula[5] = ' 0'

matricula[5] is not part of the vector matricula and here we have a problem. The interesting thing is that matricula[5] is where your name vector starts, that is, &matricula[5] == &nome[0]. So when you add a name, the character \0 will be replaced by the first letter of the name typed. An example for the name Carlos:

matricula[5] = ' 0' // Eh equal to name[0]

name[0] = 'C' // '0' has been replaced by 'C'

name[1] = 'a'

name[2] = 'r'

name[3] = 'l'

name[4] = 'o'

name[5] = ’s'

name[6] = ' 0'

When using %s, in the printf, to print the registration, the program will go through everything until you find a \0. The program will only stop when the \0 is found, as the next \0 it is after Carlos, soon Carlos will also be printed. To resolve this just leave a location between char matricula[5]; and char nome[50];, in that location will be the \0. Just do it in your code:

// Agora o '\0' ficará na matricula[5], que não faz parte do nome
// ou de qualquer outro lugar do seu programa, mas faz parte do vetor matricula
char matricula[6];

Remember to leave 1 space for the character \0 when creating string. If you want a n size, so declare n+1.

prints 3 of 6 records

The problem is in your list, in this passage in question:

else if ((strcmp(aux->nome, nome)) < 0) // elemento a ser inserido maior

That part of your code always has to be true, otherwise there will be strings not going to the list. Note that before that else if you check whether the string will be at the beginning. Well, if the string cannot get started so you need to scroll through the list to find a location for it regardless of the string, it will have to be placed in the list if you make a selection with the if, then who is flunked by this selection (when the if is false) will not enter the list. As the insertion codes at the end and in the middle are inside the if, then only who is approved will go to the list and this generates the logical error. There are 3 string who are failing the if (are the 3 that do not appear in the printf) and that’s why they’re not on your list.

To solve this just remove the if and leave only the else. Example:

// Remova isso
else if ((strcmp(aux->nome, nome)) < 0) // elemento a ser inserido maior

// E deixe assim
else

Your code looks like this with these two changes:

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

typedef struct registro
{
    //char matricula[5];
    char matricula[6];
    char nome[50];
    char genero;
    float salario;
    char cargo;
    char setor[2];
}registro;

typedef struct tiplista
{
    struct elem *inicio;
    struct elem *fim;
}tiplista;

typedef struct elem
{
    char nome[50];
    struct elem *ant;
    struct elem *prox;
    int pos; // posição do elemento no arquivo binário
}elem;

void insercao_lista_ordenada(tiplista *lista, char nome[50], int posicao)
{
    elem *aux;
    elem *novoelemento=(elem*)malloc(sizeof(elem));
    strcpy(novoelemento->nome,nome);
    novoelemento->prox= NULL;
    novoelemento->ant= NULL;
    novoelemento->pos=posicao;
    if(lista->inicio == NULL) //lista vazia
    {
        lista->inicio=novoelemento;
        lista->fim=novoelemento;
    }
    else
    {
        aux = lista->inicio; // pont aux recebe o ponteiro do início da lista
        while((aux->prox != NULL) && (strcmp(aux->nome, nome) < 0))
        {
            aux = aux->prox;
        }
        // verificar se a inserção no início
        if((aux == lista->inicio) && ((strcmp(aux->nome, nome)) > 0))
        {
            novoelemento->prox = lista->inicio;
            lista->inicio->ant = novoelemento;
            lista->inicio = novoelemento;
        }
        // else if ((strcmp(aux->nome, nome)) < 0) // elemento a ser inserido maior
        else
        {
            // verificar se a inserção no final
            if (aux == lista->fim)
            {
                novoelemento->ant = lista->fim;
                lista->fim->prox = novoelemento;
                lista->fim = novoelemento;
            }
            else // inserção no meio
            {
                novoelemento->ant = aux->ant;
                aux->ant->prox = novoelemento;
                novoelemento->prox = aux;
                aux->ant = novoelemento;
            }
        }
    }

    return;
}

void imprimir_lista(tiplista *lista)
{
    elem *aux;
    registro reg;
    FILE *arq_bin_p;
    if((arq_bin_p=fopen("arq_bin_principal.bin","rb")) == NULL)
    {
        printf("Erro: não foi possível encontrar o arquivo.");
        system("pause");
        exit(1);
    }

    aux = lista->inicio;
    while (aux != NULL) // percorre a lista
    {
        // posiciona o ponteiro do arquivo na posição do registro
        fseek (arq_bin_p, aux->pos * sizeof(registro), SEEK_SET);
        // faz a leitura do registro na posição
        fread(&reg, sizeof(registro),1 , arq_bin_p);
        printf("%s \n",reg.matricula);
        printf("%s \n",reg.nome);
        printf("%c \n",reg.genero);
        printf("%f \n",reg.salario);
        printf("%c \n",reg.cargo);
        printf("%s \n\n",reg.setor);

        aux = aux->prox; // avança para o próximo elemento da lista
    }
}

int main()
{
    registro p[6],reg;
    tiplista *lista=(tiplista*)malloc(sizeof(tiplista));
    int pos=0;
    lista->inicio=NULL;
    lista->fim=NULL;

    p[0]=(const registro){"15101","Carlos",'M',2500.00,'A',"02"};
    p[1]=(const registro){"11256", "Ana", 'F', 1850.00, 'E', "01"};
    p[2]=(const registro){"11436", "Roberto", 'M', 1550.00, 'A', "51"};
    p[3]=(const registro){"11354", "José", 'M' ,1350.00, 'D', "04"};
    p[4]=(const registro){"12542", "Elaine", 'F', 2750.00, 'B', "22"};
    p[5]=(const registro){"00812", "Murilo", 'M', 3500.00, 'E', "01"};

    FILE *arq_bin_p=fopen("arq_bin_principal.bin","wb");
    fwrite(p, sizeof(registro),6,arq_bin_p);

    fclose(arq_bin_p);

    if((arq_bin_p=fopen("arq_bin_principal.bin","rb")) == NULL)
    {
        printf("Erro: não foi possível encontrar o arquivo.");
        system("pause");
        exit(1);
    }

    while(fread(&reg,sizeof(registro),1,arq_bin_p))
    {
        insercao_lista_ordenada(lista,reg.nome,pos);
        pos++;
    }
    fclose(arq_bin_p);
    imprimir_lista(lista);

    system("pause");
    return 0;
}
  • 1

    It helped a lot, vlw!!

Browser other questions tagged

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