Problem in ordered insertion code of structs (records) in files

Asked

Viewed 462 times

1

I am doing a work in which I have to insert structs in alphabetical order in archives, in which the structs are political and the archives (which together form a chained list) are the parties. I’m having trouble inserting politics in an orderly fashion into the archives.

The algorithm I made works (or should work) as follows:

1 - The user chooses the party in which he wishes to insert the politician;

2 - The user fills in the name and surname of the politician;

3 - The program inserts the policy into the party file if it is empty;

4 - If the file is not empty, a new file is created and the elements of the old file and the newly added user policy are passed to the new file in order;

5 - The old file is deleted and the new file is named after the old one;

The program is inserting the elements in the correct order, but when it reaches a certain (small) number of elements, the new ones overwrite the old ones. So the archive only gets two or three politicians.

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

   typedef struct Politico
{
  char nome[30];
  int idade;
  int suspeita;   //de 0 a 3
}politico;

typedef struct Partido
{
  FILE* fp;   //file pointer
  char sigla[20];
  void* proximo;
}partido;

void inserirPoliticoOrdenado(partido** first)
{
  char sigla[20];
  char sobrenome[30];
  partido* party;
  politico novoPol;
  politico auxiliar;
  int inserirNovo = 0;
  politico menor;
  FILE* newfile;
  int contador = 0;
  int contador2 = 0;
  int teste;

  printf("Digite a sigla do partido em que deseja cadastrar o político\n");
  scanf("%s", sigla);

  getchar();

  party = buscarElemento(first, sigla);  //A função buscarElemento procura na lista encadeada o partido com a sigla digitada pelo usuário e retorna um ponteiro para esse partido. Se for necessário, posso postá-la aqui

  strcat(sigla, ".txt");

  if (party == NULL)
  {
    printf("O partido que procura não existe!!!\n");
  }

  if (party->fp == NULL)
  {
    printf("O partido que procura não está aberto.\n");
  }

  else
  {
    printf("\nDigite o primeiro nome do político que deseja adicionar.\n");
    fgets(novoPol.nome, 30, stdin);

    retirar_enter_de_fgets(novoPol.nome, 30);

    printf("\nDigite o sobrenome do político que deseja adicionar.\n");
    fgets(sobrenome, 30, stdin);

    retirar_enter_de_fgets(sobrenome, 30);

    adicionarEspacoAoFinalDeString(novoPol.nome);  //Para que ao concatenar o resultado não seja "NomeSobrenome", e sim "Nome Sobrenome"

    strcat(novoPol.nome, sobrenome);

    rewind(party->fp);  //Volta para o início do arquivo

    if (fread(&auxiliar, sizeof(politico), 1, party->fp) != 1) //Se o arquivo estiver vazio
    {
      rewind(party->fp);
      fwrite(&novoPol, sizeof(politico), 1, party->fp);
    }

    else //Se o arquivo não estiver vazio
    {
      newfile = fopen("newfile.txt", "wb+");  //Abre um novo arquivo

      rewind(party->fp);

      rewind(newfile);

      while (fread(&auxiliar, sizeof(politico), 1, party->fp) == 1)
      {
        if (inserirNovo == 0)  //Se o novo político já estiver inserido, esta variável será igual a 1
        {
          menor = novoPol;
        }

        else
        {
          menor = auxiliar;
        }

        if (strcmp(auxiliar.nome, menor.nome) <= 0)  //Se o nome do auxiliar for menor que o nome do menor
        {
          menor = auxiliar;

          fseek(newfile, (contador2) * sizeof(politico), SEEK_SET);

          fwrite(&menor, sizeof(politico), 1, newfile);  //Insere o politico de menor nome no novo arquivo

          contador++;

          contador2++;

          fseek(party->fp, contador * sizeof(politico), SEEK_SET); //Recomeçará a leitura na posição abaixo da anterior
        }

        else if (strcmp(menor.nome, novoPol.nome) == 0)  //Se o novo politico for o menor
        {
          fseek(newfile, (contador2) * sizeof(politico), SEEK_SET);  //Vai para a posição em que se deve inserir a struct no novo arquivo

          fwrite(&menor, sizeof(politico), 1, newfile);  //Escreve a struct no novo arquivo

          contador2++;

          fseek(party->fp, contador * sizeof(politico), SEEK_SET);

          inserirNovo = 1;
        }
      }

      if (inserirNovo == 0)  //Se a nova struct for "maior" que todas as outras, ela é inserida por último
      {
        fseek(newfile, (contador2) * sizeof(politico), SEEK_SET);

        fwrite(&novoPol, sizeof(politico), 1, newfile);
      }

      fclose(newfile);
      remove(sigla);   //Apaga o arquivo antigo
      rename("newfile.txt", sigla);   //Renomeia o novo arquivo de modo que este fique com o nome do arquivo antigo.
    }
  }
}

1 answer

0

The problem is that you will never fall into the second condition (you already treat the case of returning zero in the first).

    if (strcmp(auxiliar.nome, menor.nome) <= 0)
    {...}
    else if (strcmp(menor.nome, novoPol.nome) == 0) 
    {...}

Should be something:

    if (strcmp(auxiliar.nome, menor.nome) < 0)
    {...}
    else if (strcmp(menor.nome, novoPol.nome) == 0) 
    {...}

A tip for efficiency. You don’t need the fseek you are using, because FILE structures keep where you are in the file.

Browser other questions tagged

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