Saving stream to a file

-1

I'm having the following problem, when saving the struct, to position 1, ends up losing street, city and state value. I do not understand why this happens if in the following positions it allocates in a normal way, and the code to do such thing is the same. The problem I imagine is in the save_text () function, because if I display the fields before saving it normally shows, then the allocation in the insert must be correct.

/*
 * 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 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 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) {
        tam++;
        posicao = tam;
        info = realloc(info, tam + 1 * sizeof (struct end));
    }
    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
}

/*
 * 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() {
    int flag = 0;
    FILE *arquivo;
    int i;
    free(info);
    info = malloc(sizeof (struct end));
    arquivo = fopen("dados.txt", "r");
    tam = 0;
    while (!feof(arquivo)) {
        if (flag != 0)
            tam++;
        info = realloc(info, tam + 1 * sizeof (struct end));
        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);
        flag = 1; //altera a flag para na próxima vez começar a alocação de memória
    }
    fclose(arquivo);
    tam = i;
}
'; 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) { tam++; posicao = tam; info = realloc(info, tam + 1 * sizeof (struct end)); } 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 } /* * 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() { int flag = 0; FILE *arquivo; int i; free(info); info = malloc(sizeof (struct end)); arquivo = fopen("dados.txt", "r"); tam = 0; while (!feof(arquivo)) { if (flag != 0) tam++; info = realloc(info, tam + 1 * sizeof (struct end)); 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); flag = 1; //altera a flag para na próxima vez começar a alocação de memória } fclose(arquivo); tam = i; }
    
asked by anonymous 26.11.2014 / 14:42

1 answer

3
    info = realloc(info, (tam + 1) * sizeof (struct end));
    //                   ^       ^

But you will waste memory for 1 object.

As you increment tam before realloc you do not need to add 1 . Do not forget that in an array (or dynamic allocation space) with space for three elements, these elements have 0 , 1 , and 2 .

    
26.11.2014 / 15:21