Saving stream in a file

Asked

Viewed 142 times

-1

I have the following problem, saving the struct, the position 1, ends up losing the value of street, city and state. I do not understand why this happens if in the following positions it allocates in a normal way, and the code to do such a thing is the same. The problem I imagine is in function salva_text(), why if I display the fields before saving it shows normally, so the allocation in the insertion 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] = '\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) {
        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] != '\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() {
    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;
}

1 answer

3


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

But you’ll waste memory for one object.

How do you increase the tam before the realloc don’t need to add 1.
Don’t forget that in an array (or dynamic allocation space) with space for three elements, these elements have the indices 0, 1, and 2.

  • But this function does not change the writing of the file, where I believe the error is.

  • If you have the computer access data in a place that "does not exist" and have it printed out, and it prints out nonsense .... the problem lies in printing or accessing the data????

  • This is what I do not understand, why when I access the data an undetermined number of times, it displays, if I order it to do this, after saving it does not display, however in the save it just passes the stream to a file, and does not change the same. Should change only in the read text function...

Browser other questions tagged

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