Jump to content

Estruturas e ficheiros binarios


bushin
Go to solution Solved by TheDark,

Recommended Posts

Pessoal preciso de ajuda, o programa esta a gravar lixo ou seja qdo introduzo o 1º valor = 1 e 2º valor = 1, o resultado final deveria ser 2,3 e 3. fechando  o programa e voltando a executar o programa  escolhendo a segunda opçao mostrar dados anteriores ele estoira ou seja estoira na função void le_valores(struct struct_empresa *p)

#include <stdio.h>
#include <Windows.h>
#include <conio.h>

struct struct_empresa;

struct struct_empresa{

float liq_geral;
float liq_reduzida;
float liq_imediata;
}dados[3];

void liquidez(void);
void le_valores(struct struct_empresa *);
void guardar_valores(struct struct_empresa);


void main(void){
struct struct_empresa x;


int opcao;

printf("(prima 1) para calcular a liquidez\n");

printf("(prima 2)mostrar dados anteriores\n\n");




do{
	printf("(Escolha a opcao) ");
	opcao=getch();
	switch (opcao){
		case '1':
			system("cls");
			liquidez();
			break;

		case'2':
			system("cls");
			struct struct_empresa *data;
			le_valores(data);
			printf("liquidez geral %d\n liq_reduzida: %d\n liq_imediata: %d\n",data->liq_geral, data->liq_reduzida, data->liq_imediata);
			break;
		default:
			printf( "Op%c%co inv%clida!!! ",135,132,160);getch();	
			printf( "                           ");
			break;
	}
} while (opcao!='27');
}



void liquidez(){
float prim;
float seg;
float liq_g;
float liq_r;
float liq_i;
struct_empresa liquid;

printf("introduza o primeiro numero: \n");
scanf("%.2f",&prim);
fflush(stdin);
printf("introduza o segundo numero: \n");
scanf("%.2f",&seg);
//liquidez geral
liq_g=prim+seg;
liquid.liq_geral=liq_g;

printf("liquidez geral: %.2f\n",liquid.liq_geral);

//liquidez reduzida
liq_r=(prim*2)+seg;
liquid.liq_reduzida=liq_r;
printf("liquidez reduzida: %.2f\n",liquid.liq_reduzida);

//liquidez imediata
liq_i=prim+(seg*2);
liquid.liq_imediata=liq_i;
printf("liquidez imediata: %.2f\n",liquid.liq_imediata);

guardar_valores(liquid);

}


void guardar_valores(struct struct_empresa liquid){

FILE *Liq;
Liq=fopen("experiencia.dat","wb");

if (!Liq)
{
	printf("Erro a guardar ....!!");
}


fwrite(&liquid,sizeof(struct struct_empresa),1,Liq);
fclose(Liq);

}


void le_valores(struct struct_empresa *p){

FILE *Liq;

if((Liq=fopen("experiencia.dat","rb"))==NULL)
	printf("Erro\n");

fread((struct struct_empresa*)p,sizeof(struct struct_empresa),1,Liq);

//printf("liquidez geral %d\n liq_reduzida: %d\n liq_imediata: %d\n",p->liq_geral, p->liq_reduzida, p->liq_imediata);
fclose(Liq);
}
Link to comment
Share on other sites

SOS- urgente!!

ja consegui resolver alguns problemas, mas continua a estoirar qdo consulto os dados anteriores

#include <stdio.h>
#include <Windows.h>
#include <conio.h>

struct struct_empresa;

struct struct_empresa{

float liq_geral;
float liq_reduzida;
float liq_imediata;
};

void liquidez(void);
void guardar_valores(struct struct_empresa liquid);
void mostrar_dados(void);



int main(){


//struct struct_empresa data;
int opcao;

printf("(prima 1) para calcular a liquidez\n");

printf("(prima 2)mostrar dados anteriores\n\n");


do{
printf("(Escolha a opcao) ");
opcao=getch();
switch (opcao){
case '1':
system("cls");
liquidez();
break;
case'2':
system("cls");
mostrar_dados();
break;
default:
printf( "Op%c%co inv%clida!!! ",135,132,160);getch();
printf( " ");
break;
}
} while (opcao!='27');
return (0);
}


void liquidez(void){
float prim;
float seg;
float liq_g;
float liq_r;
float liq_i;
struct_empresa liquid;

printf("introduza o primeiro numero: \n");
scanf("%f",&prim);
fflush(stdin);
printf("introduza o segundo numero: \n");
scanf("%f",&seg);
//liquidez geral
liq_g=prim+seg;
liquid.liq_geral=liq_g;

printf("liquidez geral: %f\n",liquid.liq_geral);

//liquidez reduzida
liq_r=(prim*2)+seg;
liquid.liq_reduzida=liq_r;
printf("liquidez reduzida: %f\n",liquid.liq_reduzida);

//liquidez imediata
liq_i=prim+(seg*2);
liquid.liq_imediata=liq_i;
printf("liquidez imediata: %f\n",liquid.liq_imediata);

guardar_valores(liquid);

}

void guardar_valores(struct struct_empresa liquid){

FILE *Liq;
Liq=fopen("experiencia.dat","wb");

if (!Liq)
{
printf("Erro a guardar ....!!");
}


fwrite(&liquid,sizeof(struct struct_empresa),1,Liq);
fclose(Liq);

}


void mostrar_dados(void){

FILE *Liq;

struct_empresa *p;
//system("clear");

if((Liq=fopen("experiencia.dat","rb"))==NULL){
printf("Erro\n");
}

fread(p,sizeof(struct struct_empresa),1,Liq);

printf("liquidez geral %f\n liq_reduzida: %f\n liq_imediata: %f\n",p->liq_geral, p->liq_reduzida, p->liq_imediata);


fclose(Liq);

}
Link to comment
Share on other sites

Acho que já te resolvi os problemas.

Aqui vi o código alterado acho que comentei todas as alterações as que não estiverem é porque não eram necessárias.

Ah, já me ia esquecendo, isto não é C++ mas sim C postas-te na secção errada.

#include <stdio.h>
#include <Windows.h>
#include <conio.h>

//struct struct_empresa;    //desnecessario

/*
struct struct_empresa{

float liq_geral;
float liq_reduzida;
float liq_imediata;
}
*/

/* Com o uso do typedef define-se um novo tipo de dados
isto e defini o tipo EMPRESA e podes usar da mesma
maneira q usas um inteiro EX: int a; EMPRESA b;
gosto de fazer desta maneira para nao estar sempre
a escrever struct.
*/


typedef struct struct_empresa{

float liq_geral;
float liq_reduzida;
float liq_imediata;
}EMPRESA;




void liquidez(void);
//void guardar_valores(struct struct_empresa liquid);
void guardar_valores(EMPRESA liquid);
void mostrar_dados(void);



int main(){


//struct struct_empresa data;
int opcao;

printf("(prima 1) para calcular a liquidez\n");

printf("(prima 2)mostrar dados anteriores\n\n");


do{
printf("(Escolha a opcao) ");
opcao=getch();
switch (opcao){
case '1':
system("cls");
liquidez();
break;
case'2':
system("cls");
mostrar_dados();
break;
default:
printf( "Op%c%co inv%clida!!! ",135,132,160);getch();
printf( " ");
break;
}
} while (opcao!='27');
return (0);
}


void liquidez(void){
float prim;
float seg;
float liq_g;
float liq_r;
float liq_i;
//struct_empresa liquid;
EMPRESA liquid;

printf("introduza o primeiro numero: \n");
scanf("%f",&prim);
fflush(stdin);
printf("introduza o segundo numero: \n");
scanf("%f",&seg);
//liquidez geral
liq_g=prim+seg;
liquid.liq_geral=liq_g;

printf("liquidez geral: %f\n",liquid.liq_geral);

//liquidez reduzida
liq_r=(prim*2)+seg;
liquid.liq_reduzida=liq_r;
printf("liquidez reduzida: %f\n",liquid.liq_reduzida);

//liquidez imediata
liq_i=prim+(seg*2);
liquid.liq_imediata=liq_i;
printf("liquidez imediata: %f\n",liquid.liq_imediata);

guardar_valores(liquid);

}

//void guardar_valores(struct struct_empresa liquid){
void guardar_valores(EMPRESA liquid){
FILE *Liq=fopen("experiencia.dat","wb");

if (!Liq)
{
printf("Erro a guardar ....!!");
}


fwrite(&liquid,sizeof(liquid),1,Liq);
fclose(Liq);

}


void mostrar_dados(void){

FILE *Liq=fopen("experiencia.dat","rb");

/*
  O teu erro estava aqui a frente, pq tavas a criar um ponteiro
   para a estrutura, mas nao estavas a alocar espaco para a
   estrutura em si por isso q crashava sempre
   */
EMPRESA *p=(EMPRESA *)malloc(sizeof(EMPRESA));
//struct_empresa *p;
//system("clear");

if(Liq==NULL){
printf("Erro\n");
}

fread(p,1,sizeof(EMPRESA),Liq);  //tinhas a sintaxe errada

printf("liquidez geral %f\n liq_reduzida: %f\n liq_imediata: %f\n",p->liq_geral, p->liq_reduzida, p->liq_imediata);


fclose(Liq);

}
Link to comment
Share on other sites

Tens razão TheDark, ? como era a primeira vez q estava a usar o forum, atrapalhei-me um pouco.

Surgiu-me outra questão :wallbash:

Acresentei mais duas funçoes (ESTRUTURA_ENDIVIDAMENTO(); AUTONOMIA_FINANCEIRA() 😉 ao codigo e deu barraca, quando peço para mostrar os dados do ficheiro , devolve lixo.

#include <stdio.h>
#include <Windows.h>
#include <conio.h>



typedef struct struct_empresa{

float liq_geral;
float liq_reduzida;
float liq_imediata;
float autonomia_f;
float estrutura_e;
}EMPRESA;


void liquidez(void);
void guardar_valores(EMPRESA liquid);
void mostrar_dados(void);
void ESTRUTURA_ENDIVIDAMENTO(void);
void AUTONOMIA_FINANCEIRA(void);


int main(){

int opcao;

printf("\n----------- MENU --------------\n\n");
printf("(prima 1) para dar inicio ao estudo\n");
printf("(prima 2)mostrar dados anteriores\n\n");


do{
	printf("(Escolha a opcao) ");
	opcao=getch();
	switch (opcao){
case '1':
	system("cls");
	liquidez();
	break;
case'2':
	system("cls");
	mostrar_dados();
	break;
default:
	printf( "Op%c%co inv%clida!!! ",135,132,160);getch();
	printf( " ");
	break;
	}
} while (opcao!='27');
return (0);
}


void liquidez(void){
float prim;
float seg;
float liq_g;
float liq_r;
float liq_i;

EMPRESA liquid;
printf("\n----------- Liquidez --------------\n");
printf("\nintroduza o primeiro numero: ");
scanf("%f",&prim);
fflush(stdin);
printf("introduza o segundo numero: ");
scanf("%f",&seg);
printf(" \n");
//liquidez geral
liq_g=prim+seg;
liquid.liq_geral=liq_g;

printf("liquidez geral: %f\n",liquid.liq_geral);

//liquidez reduzida
liq_r=(prim*2)+seg;
liquid.liq_reduzida=liq_r;
printf("liquidez reduzida: %f\n",liquid.liq_reduzida);

//liquidez imediata
liq_i=prim+(seg*2);
liquid.liq_imediata=liq_i;

printf("\nliquidez imediata: %f\n",liquid.liq_imediata);
guardar_valores(liquid);

printf("\n----------- Autonomia Financeira --------------\n");
AUTONOMIA_FINANCEIRA();

}
void AUTONOMIA_FINANCEIRA(void){

float prim_a;
float seg_b;
float aut;
EMPRESA autonomia;

printf("introduza o primeiro numero: ");
scanf("%f",&prim_a);
fflush(stdin);
printf("\nintroduza o segundo numero: ");
scanf("%f",&seg_b);

aut=seg_b+prim_a;
autonomia.autonomia_f=aut;

printf("\nAutonomia = %f\n",autonomia.autonomia_f);
guardar_valores(autonomia);

printf("\n ------------ EStrutura de endividamento: ------------------\n");
ESTRUTURA_ENDIVIDAMENTO();
}

void ESTRUTURA_ENDIVIDAMENTO(void){

float est;
float prim_c;
float seg_d;

EMPRESA estutura;

printf("introduza o primeiro numero: ");
scanf("%f",&prim_c);
fflush(stdin);
printf("introduza o segundo numero: ");
scanf("%f",&seg_d);

est=prim_c+seg_d;
estutura.estrutura_e=est;

printf("\nEstrutura de endividamento: %f\n",estutura.estrutura_e);
guardar_valores(estutura);
main();
}

void guardar_valores(EMPRESA liquid){
FILE *Liq=fopen("experiencia.dat","wb");

if (!Liq)
{
	printf("Erro a guardar ....!!");
}
fwrite(&liquid,sizeof(liquid),1,Liq);
fclose(Liq);
}

void mostrar_dados(void){

FILE *Liq=fopen("experiencia.dat","rb");

//Ponteiro para a estrutura, para alocar espaco para a estrutura porque senão crasha sempre q utilize a funçao mostrar_dados

EMPRESA *p=(EMPRESA *)malloc(sizeof(EMPRESA));

if(Liq==NULL){
	printf("Erro\n");
}

fread(p,1,sizeof(EMPRESA),Liq);
printf("liquidez geral %f\n liq_reduzida: %f\n liq_imediata: %f\n",p->liq_geral, p->liq_reduzida, p->liq_imediata);
printf("\n Autonomia Finaceira: %f",p->autonomia_f);
printf("\n Estrutura de Endividamento:%f ",p->estrutura_e);
fclose(Liq);

}
Link to comment
Share on other sites

  • Solution

Dá lixo porque escreveste lixo para o ficheiro. Sempre que chamas a função guardar_valores dás-lhe como argumento uma estrutura que não tem todos os campos preenchidos.

Na função liquidez crias uma instância de EMPRESA (liquid) e preenches os campos liq_geral, liq_reduzida e liq_imediata, e de seguida chamas a função gurdar_valores passando como argumento liquid.

Depois chamas a função AUTONOMIA_FINANCEIRA, onde crias uma nova instância de EMPRESA (autonomia) e apenas preenches o campo autonomia_f, deixando os outros com lixo, e chamas de novo guardar_valores, agora passando autonomia como argumento. Isto vai recriar o ficheiro com lixo em todos os campos menos autonomia_f.

Por fim, chamas a função ESTRUTURA_ENDIVIDAMENTO, onde crias ainda outra instância de EMPRESA (estutura), e desta vez preenches o campo estrutura_e, deixando os outros com lixo, e chamas guardar_valores com estutura como argumento. Como anteriormente, isto vai recriar o ficheiro com lixo em todos os campos menos estrutura_e.

Assim, quando vais ler do ficheiro para a estrutura, só o campo estrutura_e é que não tem lixo. Tens duas hipóteses para resolver isto: ou crias uma instância global de EMPRESA, a qual utilizas em todas as funções, ou vais passando a mesma estrutura como argumento sucessivamente. Em qualquer dos casos, só precisas de guardar no ficheiro quando todos os campos estão preenchidos, qu é omo quem diz na função ESTRUTURA_ENDIVIDAMENTO.

Já agora, não chames a função main. 1º porque não é aconselhável, e 2º porque não é necessário, pois ao saíres das funções vais regressando à função anterior, e eventualmente regressas à main.

Desaparecido.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.