Problem in orderly insertion of structs into records

1

I'm doing a job where I have to insert structs in alphabetical order into files, where the structs are political and the files (which together form a linked list) are the parties. I'm having a hard time figuring out how to insert politicians in the files.

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

1 - The user chooses the party in which he wants to enter the politician;

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

3 - The program inserts the politician in the party's 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 policy are added in order to the new file;

5 - The old file is deleted and the new file is renamed;

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 file 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.
    }
  }
}
    
asked by anonymous 11.06.2017 / 04:51

1 answer

0

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

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

It should be something:

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

A tip for efficiency. You do not need the fseek that you are using, because FILE structures store where you are in the file.

    
14.08.2017 / 19:01