I have the algorithm that simulates a type of register, but when I save the file the fields, street, city and state are lost, they simply disappear, and as I am saving it it corrupts the file already at the time of writing. I can not figure out why this is happening. This case is very specific, it only happens after inserting two elements or more, and saving the struct , if I do not save it the fields remain unchanged, I imagine that's why it is in the "save_text" function but I'm still not sure, so I'm posting all code:
/*
* File: main.c
* Author: pmargreff
*
* Created on 6 de Novembro de 2014, 00:25
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct end {
char nome[100];
char rua[100];
char cidade[100];
char estado[100];
unsigned long int cep;
} *info;
/*
* struct para conseguir comparar
* dois nomes em diversas funções
*/
struct compara {
char nome[100];
} busca;
int flag = 0; // flag sinaliza é ativada quando o cadastro é acessado pela primeira vez
int tam = 0; //cria uma váriavel para que guardar o tamanho do vetor
void cria_lista(void);
void insere(void);
void apaga(void);
void pesquisa(void);
void imprime(void);
int menu(void);
int livre(void);
int busca_nome(void);
void ler_string(char palavra[100], int tamanho);
void salva_texto(void);
void le_texto(void);
int main(void) {
int escolha;
cria_lista();
for (;;) {
escolha = menu();
switch (escolha) {
case 1: insere();
break;
case 2: apaga();
break;
case 3: imprime();
break;
case 4: pesquisa();
break;
case 5: salva_texto();
break;
case 6: le_texto();
break;
default: return 0;
break;
}
}
}
//aloca o suficiente para uma váriavel e armazena /0 na mesma
void cria_lista(void) {
info = malloc(sizeof (struct end));
}
int menu(void) {
int c = 0;
do {
printf("-- MENU:\n");
printf("\t 1. Inserir um nome\n");
printf("\t 2. Excluir um nome\n");
printf("\t 3. Listar o arquivo\n");
printf("\t 4. Pesquisar um nome\n");
printf("\t 5. Salvar em arquivo\n");
printf("\t 6. Abrir arquivo\n");
printf("\t 7. Sair\n");
printf("-- Digite sua escolha: ");
scanf("%d", &c);
} while (c <= 0 || c > 8);
getchar();
return c;
}
void ler_string(char palavra[100], int tamanho) {
int i = 0;
char c;
c = getchar();
while ((c != '\n') && (i < tamanho)) {
palavra[i++] = c;
c = getchar();
}
palavra[i] = '/*
* File: main.c
* Author: pmargreff
*
* Created on 6 de Novembro de 2014, 00:25
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct end {
char nome[100];
char rua[100];
char cidade[100];
char estado[100];
unsigned long int cep;
} *info;
/*
* struct para conseguir comparar
* dois nomes em diversas funções
*/
struct compara {
char nome[100];
} busca;
int flag = 0; // flag sinaliza é ativada quando o cadastro é acessado pela primeira vez
int tam = 0; //cria uma váriavel para que guardar o tamanho do vetor
void cria_lista(void);
void insere(void);
void apaga(void);
void pesquisa(void);
void imprime(void);
int menu(void);
int livre(void);
int busca_nome(void);
void ler_string(char palavra[100], int tamanho);
void salva_texto(void);
void le_texto(void);
int main(void) {
int escolha;
cria_lista();
for (;;) {
escolha = menu();
switch (escolha) {
case 1: insere();
break;
case 2: apaga();
break;
case 3: imprime();
break;
case 4: pesquisa();
break;
case 5: salva_texto();
break;
case 6: le_texto();
break;
default: return 0;
break;
}
}
}
//aloca o suficiente para uma váriavel e armazena /0 na mesma
void cria_lista(void) {
info = malloc(sizeof (struct end));
}
int menu(void) {
int c = 0;
do {
printf("-- MENU:\n");
printf("\t 1. Inserir um nome\n");
printf("\t 2. Excluir um nome\n");
printf("\t 3. Listar o arquivo\n");
printf("\t 4. Pesquisar um nome\n");
printf("\t 5. Salvar em arquivo\n");
printf("\t 6. Abrir arquivo\n");
printf("\t 7. Sair\n");
printf("-- Digite sua escolha: ");
scanf("%d", &c);
} while (c <= 0 || c > 8);
getchar();
return c;
}
void ler_string(char palavra[100], int tamanho) {
int i = 0;
char c;
c = getchar();
while ((c != '\n') && (i < tamanho)) {
palavra[i++] = c;
c = getchar();
}
palavra[i] = '%pre%';
if (c != '\n') {
c = getchar();
while ((c != '\n') && (c != EOF)) {
c = getchar();
}
}
}
void insere(void) {
int aux;
int posicao = tam;
if (flag == 1) {
printf("-- Registro %d:\n", posicao + 1);
} else {
printf("-- Registro %d:\n", posicao);
}
printf("\t Nome: ");
ler_string(busca.nome, 30);
aux = busca_nome(); /*confere se já existe nome */
if (aux != -1) { /*caso exista apenas volta ao menu anterior */
return;
}
/*
* quando a flag está ativa, aloca memória de acordo com o número de vezes que passa no vetor
*/
if (flag == 1) {
info = realloc(info, 1);
tam++;
posicao = tam;
}
strcpy(info[posicao].nome, busca.nome);
printf("\t Rua: ");
ler_string(info[posicao].rua, 40);
printf("\t Cidade: ");
ler_string(info[posicao].cidade, 20);
printf("\t Estado: ");
ler_string(info[posicao].estado, 2);
printf("\t CEP: ");
scanf("%lu", &info[posicao].cep);
flag = 1; //ativa a flag
}
/*
* percorre o vetor e se encontra alguma posição livre
* devolve o indice dessa posição de memória, caso contrário
* apenas retorna -1
*/
int livre(void) {
int i;
for (i = 0; i <= tam; i++) {
if (info[i].nome[0] == '%pre%')
return i;
}
return -1;
}
/*
* chama a funçao busca_nome que retorna o indice
* para a variavel posicão que devera ser apagado
* se nenhum nome igual for encontrado retorna -1
*/
void apaga(void) {
int posicao;
int confirma;
ler_string(busca.nome, 30);
posicao = busca_nome();
if (posicao >= 0 && posicao < tam) {
printf("Você realmente deseja apagar %s?\n0-não\n1-sim", info[posicao].nome);
scanf("%d", &confirma);
if (confirma == 1) {
info[posicao] = info[tam];
tam--;
}
}
}
void imprime(void) {
int i;
for (i = 0; i <= tam; i++)
if (info[i].nome[0] != '%pre%') {
printf("-- Registro %d:\n", i);
printf("\t Nome: %s", info[i].nome);
printf("\t Rua: %s", info[i].rua);
printf("\t Cidade: %s", info[i].cidade);
printf("\t Estado: %s\n", info[i].estado);
printf("\t CEP: %lu\n", info[i].cep);
}
}
/*
* função que faz a busca de um nome no programa
* le o nome que está localizado na struct busca.nome
* e retorna o indice se encontrar nome igual ou
* -1 se não encontrar nome como aquele
*/
int busca_nome(void) {
int i;
for (i = 0; i <= tam; i++) {
if (strcmp(busca.nome, info[i].nome) == 0) {
return i;
}
}
return -1;
}
/* função para procurar e exibir apenas o nome desejado
* chama o função busca_nome que devolve o indice para
* a variavel i se for válido e se não existir devolve
* menos um, o a exibição só é feita quando o indice é
* diferente de menos um e menor que o máximo pré estabelecido
*/
void pesquisa(void) {
int i;
ler_string(busca.nome, 30);
i = busca_nome();
if (i >= 0 && i <= tam) {
printf("-- Registro %d:\n", i);
printf("\t Nome: %s", info[i].nome);
printf("\t Rua: %s", info[i].rua);
printf("\t Cidade: %s", info[i].cidade);
printf("\t Estado: %s\n", info[i].estado);
printf("\t CEP: %lu\n", info[i].cep);
} else {
printf("Nome não encontrado na lista!! \n\n");
}
}
/*
void salva_bin(void) {
FILE *arquivo;
int i;
arquivo = fopen("dados.bin", "w");
for (i = 0; i <= tam; i++) {
fwrite(&i, sizeof (int), 1, arquivo);
fwrite(&info[i], sizeof (struct end), 1, arquivo);
}
//fwrite(&info, MAX*sizeof(struct end), 1, arquivo);
fclose(arquivo);
}
void abre_arq(void) {
FILE *arquivo;
int i;
arquivo = fopen("dados.bin", "r");
while (!feof(arquivo)) {
fread(&i, sizeof (int), 1, arquivo);
fread(&info[i], sizeof (struct end), 1, arquivo);
}
tam = i;
//fread(&info, MAX*sizeof(struct end), 1, arquivo);
fclose(arquivo);
}
*/
void salva_texto() {
FILE *arquivo;
int i;
arquivo = fopen("dados.txt", "w");
for (i = 0; i <= tam; i++) {
fprintf(arquivo, "%d\n", i);
fprintf(arquivo, "%s\n", info[i].nome);
fprintf(arquivo, "%s\n", info[i].rua);
fprintf(arquivo, "%s\n", info[i].cidade);
fprintf(arquivo, "%s\n", info[i].estado);
fprintf(arquivo, "%lu\n", info[i].cep);
}
fclose(arquivo);
}
void le_texto() {
FILE *arquivo;
int i;
arquivo = fopen("dados.txt", "r");
while (!feof(arquivo)) {
fscanf(arquivo, "%d", &i);
fscanf(arquivo, "%[^\n]%*c", info[i].nome);
fscanf(arquivo, "%[^\n]%*c", info[i].rua);
fscanf(arquivo, "%[^\n]%*c", info[i].cidade);
fscanf(arquivo, "%[^\n]%*c", info[i].estado);
fscanf(arquivo, "%lu", &info[i].cep);
}
fclose(arquivo);
}
';
if (c != '\n') {
c = getchar();
while ((c != '\n') && (c != EOF)) {
c = getchar();
}
}
}
void insere(void) {
int aux;
int posicao = tam;
if (flag == 1) {
printf("-- Registro %d:\n", posicao + 1);
} else {
printf("-- Registro %d:\n", posicao);
}
printf("\t Nome: ");
ler_string(busca.nome, 30);
aux = busca_nome(); /*confere se já existe nome */
if (aux != -1) { /*caso exista apenas volta ao menu anterior */
return;
}
/*
* quando a flag está ativa, aloca memória de acordo com o número de vezes que passa no vetor
*/
if (flag == 1) {
info = realloc(info, 1);
tam++;
posicao = tam;
}
strcpy(info[posicao].nome, busca.nome);
printf("\t Rua: ");
ler_string(info[posicao].rua, 40);
printf("\t Cidade: ");
ler_string(info[posicao].cidade, 20);
printf("\t Estado: ");
ler_string(info[posicao].estado, 2);
printf("\t CEP: ");
scanf("%lu", &info[posicao].cep);
flag = 1; //ativa a flag
}
/*
* percorre o vetor e se encontra alguma posição livre
* devolve o indice dessa posição de memória, caso contrário
* apenas retorna -1
*/
int livre(void) {
int i;
for (i = 0; i <= tam; i++) {
if (info[i].nome[0] == '%pre%')
return i;
}
return -1;
}
/*
* chama a funçao busca_nome que retorna o indice
* para a variavel posicão que devera ser apagado
* se nenhum nome igual for encontrado retorna -1
*/
void apaga(void) {
int posicao;
int confirma;
ler_string(busca.nome, 30);
posicao = busca_nome();
if (posicao >= 0 && posicao < tam) {
printf("Você realmente deseja apagar %s?\n0-não\n1-sim", info[posicao].nome);
scanf("%d", &confirma);
if (confirma == 1) {
info[posicao] = info[tam];
tam--;
}
}
}
void imprime(void) {
int i;
for (i = 0; i <= tam; i++)
if (info[i].nome[0] != '%pre%') {
printf("-- Registro %d:\n", i);
printf("\t Nome: %s", info[i].nome);
printf("\t Rua: %s", info[i].rua);
printf("\t Cidade: %s", info[i].cidade);
printf("\t Estado: %s\n", info[i].estado);
printf("\t CEP: %lu\n", info[i].cep);
}
}
/*
* função que faz a busca de um nome no programa
* le o nome que está localizado na struct busca.nome
* e retorna o indice se encontrar nome igual ou
* -1 se não encontrar nome como aquele
*/
int busca_nome(void) {
int i;
for (i = 0; i <= tam; i++) {
if (strcmp(busca.nome, info[i].nome) == 0) {
return i;
}
}
return -1;
}
/* função para procurar e exibir apenas o nome desejado
* chama o função busca_nome que devolve o indice para
* a variavel i se for válido e se não existir devolve
* menos um, o a exibição só é feita quando o indice é
* diferente de menos um e menor que o máximo pré estabelecido
*/
void pesquisa(void) {
int i;
ler_string(busca.nome, 30);
i = busca_nome();
if (i >= 0 && i <= tam) {
printf("-- Registro %d:\n", i);
printf("\t Nome: %s", info[i].nome);
printf("\t Rua: %s", info[i].rua);
printf("\t Cidade: %s", info[i].cidade);
printf("\t Estado: %s\n", info[i].estado);
printf("\t CEP: %lu\n", info[i].cep);
} else {
printf("Nome não encontrado na lista!! \n\n");
}
}
/*
void salva_bin(void) {
FILE *arquivo;
int i;
arquivo = fopen("dados.bin", "w");
for (i = 0; i <= tam; i++) {
fwrite(&i, sizeof (int), 1, arquivo);
fwrite(&info[i], sizeof (struct end), 1, arquivo);
}
//fwrite(&info, MAX*sizeof(struct end), 1, arquivo);
fclose(arquivo);
}
void abre_arq(void) {
FILE *arquivo;
int i;
arquivo = fopen("dados.bin", "r");
while (!feof(arquivo)) {
fread(&i, sizeof (int), 1, arquivo);
fread(&info[i], sizeof (struct end), 1, arquivo);
}
tam = i;
//fread(&info, MAX*sizeof(struct end), 1, arquivo);
fclose(arquivo);
}
*/
void salva_texto() {
FILE *arquivo;
int i;
arquivo = fopen("dados.txt", "w");
for (i = 0; i <= tam; i++) {
fprintf(arquivo, "%d\n", i);
fprintf(arquivo, "%s\n", info[i].nome);
fprintf(arquivo, "%s\n", info[i].rua);
fprintf(arquivo, "%s\n", info[i].cidade);
fprintf(arquivo, "%s\n", info[i].estado);
fprintf(arquivo, "%lu\n", info[i].cep);
}
fclose(arquivo);
}
void le_texto() {
FILE *arquivo;
int i;
arquivo = fopen("dados.txt", "r");
while (!feof(arquivo)) {
fscanf(arquivo, "%d", &i);
fscanf(arquivo, "%[^\n]%*c", info[i].nome);
fscanf(arquivo, "%[^\n]%*c", info[i].rua);
fscanf(arquivo, "%[^\n]%*c", info[i].cidade);
fscanf(arquivo, "%[^\n]%*c", info[i].estado);
fscanf(arquivo, "%lu", &info[i].cep);
}
fclose(arquivo);
}