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