Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

gRoOvE

Alocação de structs

Recommended Posts

Estou tentando fazer o exercício do 3º desafio aqui, mas ta brabo. Não estou conseguindo nem exibir os dados depois de gravados no vetor, não consigo achar o erro..segue o code:

 

#include <stdio.h>
#include <stdlib.h>
#include "MyLib.h"
#define MAX 10

typedef struct
{
	char nome[60];
	char telefone[8];
	char endereco[60];
	char cidade[60];
	char estado[2];
}Cadastro;

Cadastro *usuario;

void Menu(void);
void Cadastrar(int *qtd);
void Exibir(int qtd);


void SalvarDados(int qtd);
void CarregarDados(int qtd);

int main()
{
	int qtd = 0;
	int opcao;
	do
	{
		Menu();
		printf("Digite uma opcao: ");
		scanf("%d",&opcao);
		LimparBuffer();
		switch(opcao)
		{
			case 1:
				system("cls");
				Cadastrar(&qtd);
				break;
			case 2:
				//Editar();
				break;
			case 3:
				system("cls");
				Exibir(qtd);
				break;
			case 4:
				system("cls");
				SalvarDados(qtd);
				break;
			case 5:
				system("cls");
				CarregarDados(qtd);
				break;
			case 6:
				exit(0);
			default:
				printf("Opcao Invalida!\n");

		}
	}while(opcao != 7);
}

void Menu(void)
{
	printf("------------------------\n");
	printf("1 - CADASTRAR\n");
	printf("2 - EDITAR\n");
	printf("3 - EXIBIR\n");
	printf("4 - SALVAR\n");
	printf("5 - CARREGAR\n");
	printf("6 - SAIR\n");
}

void Cadastrar(int *qtd)
{
	usuario = (Cadastro*)malloc(50*sizeof(Cadastro));
	if(!usuario)
	{
		printf("Sem espaco em memoria!\n");
	}
	printf("Nome: ");
	scanf("%[^\n]",usuario[*qtd].nome);
	LimparBuffer();
	free(usuario);
	(*qtd)++;

	

	/*
	printf("Telefone: ");
	scanf("%8[^\n]",cadastro.telefone);
	LimparBuffer();
	
	printf("Endereco: ");
	scanf("%[^\n]",cadastro.endereco);
	LimparBuffer();
	
	printf("Cidade: ");
	scanf("%[^\n]",cadastro.cidade);
	LimparBuffer();

	printf("Estado: ");
	scanf("%2[^\n]",cadastro.estado);
	LimparBuffer();
	*/
	
}

void Exibir(int qtd)
{
	for(int i=0; i<qtd; i++)
	{
	printf("Nome: %s\n",*usuario[i].nome);
	}
}

void SalvarDados(int qtd)
{
	FILE *fp;

	if((fp = fopen("Cadastro_usuarios.txt","ab")) == NULL)
	{
		printf("Nao foi possivel abrir o arquivo!\n");
		exit(1);
	}

	fwrite(usuario,sizeof(Cadastro),1,fp);
	
	fclose(fp);
}

void CarregarDados(int qtd)
{
	FILE *fp;
	int qtd_dados_carregados;
	if((fp = fopen("Cadastro_usuarios.txt","rb")) == NULL)
	{
		printf("Nao foi possivel abrir o arquivo!\n");
		exit(1);
	}
	qtd_dados_carregados = fread(&usuario,sizeof(Cadastro),1,fp);
	printf("%d dados carregados!\n");
	fclose(fp);
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

creio eu que o problema seja que você estaja alocando e logo em seguida desalocando no cadastro

 

você malloca e logo depois da free

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu tbm qria entender..

você aloca e depois jah libera a memoria?

 

[]s

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso eu arrumei já, tipo quando vou salvar agora, as vezes salva como código, as vezes como letras mesmo...e não consig recuperar o que eu salvei, diz que o ponteiro pra parte da memória q ele vai ser recuperado tá errado, olhem ae:

Obs: para fins de teste, apenas inserir 2 registros.

 

#include <stdio.h>
#include <stdlib.h>
#include "MyLib.h"
#define MAX 10

typedef struct
{
	char nome[60];
	//char telefone[8];
	//char endereco[60];
	//char cidade[60];
	//char estado[2];
}Cadastro;

Cadastro* usuario = NULL;


void Menu(void);
void Cadastrar();
void Exibir();


void SalvarDados();
void CarregarDados();

int main()
{
	int opcao;
	do
	{
		Menu();
		printf("Digite uma opcao: ");
		scanf("%d",&opcao);
		LimparBuffer();
		switch(opcao)
		{
			case 1:
				system("cls");
				Cadastrar();
				break;
			case 2:
				//Editar();
				break;
			case 3:
				system("cls");
				Exibir();
				break;
			case 4:
				system("cls");
				SalvarDados();
				break;
			case 5:
				system("cls");
				CarregarDados();
				break;
			case 6:
				exit(0);
			default:
				printf("Opcao Invalida!\n");

		}
	}while(opcao != 7);
}

void Menu(void)
{
	printf("------------------------\n");
	printf("1 - CADASTRAR\n");
	printf("2 - EDITAR\n");
	printf("3 - EXIBIR\n");
	printf("4 - SALVAR\n");
	printf("5 - CARREGAR\n");
	printf("6 - SAIR\n");
}

void Cadastrar()
{
	int reg_qtd = 0, i = 0;
	printf("Quantos registros deseja cadastrar: ");
	scanf("%d",&reg_qtd);
	LimparBuffer();
	usuario = (Cadastro*)malloc(reg_qtd * sizeof(Cadastro));
	if(!usuario)
	{
		printf("Sem espaco em memoria!\n");
	}
	for(i=0; i<reg_qtd; i++)
	{
		printf("Nome: ");
		scanf("%[^\n]",usuario[i].nome);
		LimparBuffer();
	}

	/*
	printf("Telefone: ");
	scanf("%8[^\n]",cadastro.telefone);
	LimparBuffer();
	
	printf("Endereco: ");
	scanf("%[^\n]",cadastro.endereco);
	LimparBuffer();
	
	printf("Cidade: ");
	scanf("%[^\n]",cadastro.cidade);
	LimparBuffer();

	printf("Estado: ");
	scanf("%2[^\n]",cadastro.estado);
	LimparBuffer();
	*/
	
}

void Exibir()
{
	int i;
	for(i=0; i<2; i++)
	{
		printf("Nome: %s\n",usuario[i].nome);
	}
}

void SalvarDados()
{
	FILE *fp;

	if( (fp = (fopen("Cadastro_usuarios.txt","ab")) ) == NULL)
	{
		printf("Nao foi possivel abrir o arquivo!\n");
		exit(1);
	}
	
	for(int i=0; i<2; i++)
	{
		if((fwrite(usuario+i,sizeof(Cadastro*),1,fp)) != 1)
		printf("Erro de escrita no arquivo!\n");
	}
	

	fclose(fp);


}

void CarregarDados()
{
	FILE *fp;

	if( (fp = (fopen("Cadastro_usuarios.txt","rb")) ) == NULL)
	{
		printf("Nao foi possivel abrir o arquivo!\n");
		exit(1);
	}
	for(int i=0; i<2; i++)
	{
		if((fread(usuario+i,sizeof(Cadastro*),1,fp)) != 1)
		printf("Erro de leitura no arquivo!\n");
	}

	fclose(fp);
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

você deveria alocar kd espaço do seu array Usuario..

tipo:

alocar = usuario[indice].nome

 

entendeu?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como assim cada espaço? Tipo, eu aloquei a struct toda de uma vez...em qual parte do código ta falando isso, seja mais preciso

Compartilhar este post


Link para o post
Compartilhar em outros sites

bom soh falei pra você alocar o espaço q vai utilizar no nome, + isso nem é o + importante..

antes de escrever no arquivo pq você naum monta uma linha com os dados q vai salvar e monta uma saida formatada com o sfprintf ai, sim escreve no arquivo..

c você me entendeu tente ae, senaum posta + ae ;D

 

[]s

Compartilhar este post


Link para o post
Compartilhar em outros sites

algo assim groove:

for(int i=0; i<2; i++)
	{
			sprintf(sTexto, "%s\n", usuario[i].nome);
			//grava no arquivo com o comando q você desejar
	}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiro vou tentar resolver isso, depois vejo como faz pra alocar os campos da struct individualmente.

Algo assim:

 

for(int i=0; i<2; i++)
	{
		sprintf(buf,"%s",usuario[i].nome);
		fprintf(fp,"%s\n",buf);
	}
Assim deu certo. Qual a melhor forma de guardar os dados no .txt que vai ser mais facil de acessar? Tudo numa linha? A cada linha será um registro?

 

NomeTelefoneEnderecoCidadeEstado

Bom a única forma que consegui fazer foi assim, pegando cada registro com fgets onde tem quebra de linha.

Compartilhar este post


Link para o post
Compartilhar em outros sites

quit, deixei conforme code...mas cara não consigo recuperar isso...

 

Nome $Telefone $Endereco $Cidade $Estado $

 

Tava tentando fazer assim, mas tá porco demais isso e não funciona ainda "/

for(int i=0; i<reg_qtd; i++)
	{
		fgets(linha,255,fp);
		if(linha[0] != '0')
		{
			while(linha[conta] != '$')
			{
				teste[conta] = linha[conta];
				conta++;
			}
			strcpy(usuario[reg_qtd].nome,teste);
			conta++;
			while(linha[conta] != '$')
			{
				teste1[xx] = linha[conta];
				xx++;
				conta++;
			}
			strcpy(usuario[reg_qtd].telefone,teste1);
			conta = 0;
		}
		//strcpy(usuario[i].nome,linha);
		//printf("Erro de leitura no arquivo!\n");
	}

Compartilhar este post


Link para o post
Compartilhar em outros sites

groove me desculpe, + me posicione oq você ta tentando agora?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Salva como binário, ficará BEM mais fácil e rápido...

 

você faz:

FILE *fb;
char buffer[]="testando um dois tres";
int length;

	length = strlen(buffer);

	fb = fopen("myfile.bin", "wb");


	fwrite(&length, sizeof(int), 1, fb); //primeiro escreve-se o tamanho da string
	fwrite(buffer, 1, sizeof(buffer), fb); //agora escreve-se a string

	
//para ler o processo é o mesmo, lê-se primeiro o tamanho, depois a string
	fb = fopen("myfile.bin", "rb");

	fread(&length,sizeof(int), 1, fb);
	fread(buffer, 1, length, fb);
;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tipo, no começo eu tava salvando com fwrite(), mas como to usando estrutura tava salvando tudo errado, sei lá qq eu tava fazendo errado...ai o quit sugeriu de salvar como arquivo texto formatado, me bati um pouco mas consegui salvar e recuperar eles certinho.

 

Como eu estou usando struct, e no caso os tamanhos do campos desta eram constantes, não existe a necessidade de salvar o tamanho né? Aí teria que usar o fseek() pra recuperar os dados salvos de acordo com cada campo né?

 

Se for usar o fwrite pra salvar arquivo binário tenho que usar a extensão .bin ou foi apenas um exemplo? Pois quando tentei, tava salvando como .txt "/

 

quit agora to fazendo a parte da alocação dinâmica dos campos da struct :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

A extensão você usa o que quiser, eu usei ".bin" para reforçar a idéia de que é um arquivo binário....

Uma vez tava fazendo um programa que criptografafa um texto, eu salvei os dados como binário em um arquivo .ctbl (cripto-table)

 

se você ta salvando uma struct, com tamanho constante é quase a mesma coisa:

struct numeros
{
	int x, y;
};

int main()
{
FILE *fb;
struct numeros mynum;

	mynum.x = 10;
	mynum.y = 20;

	fb = fopen("myfile.bin", "wb");
	if (!fb) printf("Erro ao abrir arquivo de escrita\n");

	fwrite(&mynum, sizeof(struct numeros), 1, fb); //agora escreve-se a struct

	fclose(fb);

	//vamos zerar a sctruct, para depois lermos os do arquivo
	mynum.x = 0;
	mynum.y = 0;
	
	//vamos agora ler os dados
	fb = fopen("myfile.bin", "rb");
	if (!fb) printf("erro ao abrir arquivo de leitura\n");

	fread(&mynum, sizeof(struct numeros), 1, fb);

	fclose(fb);

	printf(" x=%d \n y=%d \n", mynum.x, mynum.y);

 

Se você utilizar um array de structs, tem que usar fseek.

da um olhada:

http://www.nextdawn.nl/sub/c_language/c_bin_fileio.php

Compartilhar este post


Link para o post
Compartilhar em outros sites

Legal esse site Victor, adicionei aos favoritos já :D Vou terminar com arquivos de texto, depois vou implementar como binários...tipo, como disse acima tava fazendo a parte de alocação.

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MyLib.h"
#define MAX 10

typedef struct
{
	char* nome;
	char* telefone;
	char* endereco;
	char* cidade;
	char* estado;
}Cadastro;

Cadastro* usuario;

int reg_qtd = 0;
int flag = 0; //Verifica se o arquivo ja esta carregado


void Menu(void);
void Cadastrar();
void Exibir();


void SalvarDados();
void CarregarDados();

char* AlocarDados();
void CadastrarDados(char* dado);
void CadastrarDadosDoArquivo(char* point, FILE *fp);

int main()
{
	int opcao;
	do
	{
		Menu();
		printf("Digite uma opcao: ");
		scanf("%d",&opcao);
		LimparBuffer();
		switch(opcao)
		{
			case 1:
				system("cls");
				Cadastrar();
				break;
			case 2:
				//Editar();
				break;
			case 3:
				system("cls");
				Exibir();
				break;
			case 4:
				system("cls");
				SalvarDados();
				break;
			case 5:
				system("cls");
				CarregarDados();
				break;
			case 6:
				free(usuario->nome);
				free(usuario->telefone);
				free(usuario->endereco);
				free(usuario->cidade);
				free(usuario->estado);
				free(usuario);
				exit(0);
			default:
				system("cls");
				printf("Opcao Invalida!\n");

		}
	}while(opcao != 7);
}

void Menu(void)
{
	printf("------------------------\n");
	printf("1 - CADASTRAR\n");
	printf("2 - EDITAR\n");
	printf("3 - EXIBIR\n");
	printf("4 - SALVAR\n");
	printf("5 - CARREGAR\n");
	printf("6 - SAIR\n");
}

void Cadastrar()
{
	int i = 0;


	printf("Quantos registros deseja cadastrar: ");
	scanf("%d",&reg_qtd);
	LimparBuffer();
	usuario = (Cadastro*)malloc(reg_qtd * sizeof(Cadastro));
	if(!usuario) printf("Sem espaco em memoria!\n");

	for(i=0; i<reg_qtd; i++)
	{
		usuario->nome = AlocarDados();
		printf("\nNome: ");
		CadastrarDados(usuario->nome);

		usuario->telefone = AlocarDados();
		printf("Telefone: ");
		CadastrarDados(usuario->telefone);

		usuario->endereco = AlocarDados();
		printf("Endereco: ");
		CadastrarDados(usuario->endereco);

		usuario->cidade = AlocarDados();
		printf("Cidade: ");
		CadastrarDados(usuario->cidade);

		usuario->estado = AlocarDados();
		printf("Estado: ");
		CadastrarDados(usuario->estado);
	}
}

void Exibir()
{
	int i;
	for(i=0; i<reg_qtd; i++)
	{
		printf("Nome: %s\n",usuario[i].nome);
		printf("Telefone: %s\n",usuario[i].telefone);
		printf("Endereco: %s\n",usuario[i].endereco);
		printf("Cidade: %s\n",usuario[i].cidade);
		printf("Estado: %s\n",usuario[i].estado);
		printf("\n");
	}
}

void SalvarDados()
{
	FILE *fp;
	char buf[255];
	if( (fp = (fopen("Cadastro_usuarios.txt","a")) ) == NULL)
	{
		printf("Nao foi possivel abrir o arquivo!\n");
		exit(1);
	}
	
	for(int i=0; i<reg_qtd; i++)
	{
		sprintf(buf,"%s;%s;%s;%s;%s",usuario[i].nome,usuario[i].telefone,usuario[i].endereco,usuario[i].cidade,usuario[i].estado);
		fprintf(fp,"%s\n",buf);
	}
	printf("Arquivo Salvo com Sucesso!\n");
	fclose(fp);
}

void CarregarDados()
{
	FILE *fp;
	char linha[255];


	if(flag)
	{
		printf("Arquivo Ja Carregado!\n");
		return;
	}
	if((fp = (fopen("Cadastro_usuarios.txt","r"))) == NULL)
	{
		printf("Nao foi possivel abrir o arquivo!\n");
		exit(1);
	}

	while(!feof(fp))
	{
		fgets(linha,255,fp);
		reg_qtd++;
	}
	reg_qtd--; //ta sobrando uma linha em branco quando salva no arquivo

	rewind(fp);
	usuario = (Cadastro*)malloc(reg_qtd * sizeof(Cadastro));
	if(!usuario)
	{
		printf("memoria estorada!\n");
		exit(1);
	}

	for(int i=0; i<reg_qtd; i++)
	{
		//fscanf(fp,"%[^;]; %[^;]; %[^;]; %[^;]; %[^\n]\n", &nome, &telefone, &endereco, &cidade, &>estado);
		usuario->nome = AlocarDados();
		CadastrarDadosDoArquivo(usuario->nome,fp);

		usuario->telefone = AlocarDados();
		CadastrarDadosDoArquivo(usuario->telefone,fp);

		usuario->endereco = AlocarDados();
		CadastrarDadosDoArquivo(usuario->endereco,fp);

		usuario->cidade = AlocarDados();
		CadastrarDadosDoArquivo(usuario->cidade,fp);

		usuario->estado = AlocarDados();
		CadastrarDadosDoArquivo(usuario->estado,fp);

		
	}
	printf("Arquivo Carregado com Sucesso!\n");
	flag = 1;
	fclose(fp);
}

char* AlocarDados()
{
	char* dados;
	dados = (char*)malloc(MAX * sizeof(char) + 1);
	if(!dados)
		printf("Sem espaco em memoria!\n");

	return(dados);
}
void CadastrarDados(char* point)
{
	char c;
	int j=0;
	int k=0;

	while ((c = getchar()) != '\n' && c != '\0' && c != EOF)
	{
		if (j == 10)
		{
			point = (char *) realloc(point, strlen(point) + 10 * sizeof(char) + 1);
			j = 0;
		}
		*(point + k * sizeof(char)) = c;
		k++;
		j++;
	}
	*(point + k * sizeof(char)) = '\0';
}

Mas consigo alocar apenas para um registro, tipo se entro com 2 registros, vai pegar só último "/

Tava tentando fazer assim:

 

usuario[i]->nome = AlocarDados();
ou
usuario+i->nome = AlocarDados();
Por que não dá certo?

 

Outra coisa que estou fazendo errado é alocar a struct antes dos campos...como vou alocar a struct se ainda não sei o tamanho dos campos que virão?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.