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

I'm doing a job where I have to insert structs alphabetically into files, where the structs are political and the files (which together form a chained list) are the parties. I am having difficulties in the function of inserting the policies in an orderly way in the files.

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

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

2-the user fill in the name and surname of the politician;

3 - the program inserts the politico in 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 politico newly added by the user are passed in order to the new file;

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

The program is entering the elements in the correct order, but when it hits given (small) number of elements, the new ones overwrite the old ones. Thus, 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.
    }
  }
}
Author: Matews12, 2017-06-11

1 answers

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) 
    {...}

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 you are using, as the file structures store where you are in the file.

 0
Author: Gustavo Dambros, 2017-08-14 17:01:45