Stream corrupting to be saved

Asked

Viewed 56 times

0

I have the algorithm that simulates a type of registration, but when I save the file the fields, street, city and state are lost, simply disappear, and as I am saving it corrupts the file already at the time of writing. I can’t identify why this is happening. This case is very specific, it only happens after you insert two or more elements, and save the struct, if I do not save it the fields remain unchanged, I imagine that is why it is in the function "salva_text" but still not sure, then I am 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] = '\0';
    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] == '\0')
            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] != '\0') {
            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);
}

1 answer

2


    info = realloc(info, 1);

This line makes it info Now point to a memory space with 1 byte of size, which is not enough for several objects of the type struct end.

You have to know how many elements you need (possibly one more than before calling the function) and do realloc on that basis.

    struct end *tmp = realloc(info, NElems * sizeof *info);
    if (!tmp) {
        /* erro de memoria */
    }
    info = tmp; /* info aponta para um espaço capaz de guardar NElems objectos */

Browser other questions tagged

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