Jump to content

A vossa opinião...mais uma vez :)


alphasil
 Share

Recommended Posts

Oi ppl;

Estou a tentar ler um ficheiro e verificar quantos registos tem. (funciona)

Testo uma função random (funciona)

Depois quero que me vá buscar aquele registo atribuindo ao registo o valor do random (funciona)

Agora não me dá é o registo, tenho isso a funcionar noutra função mas nesta não me dá...

void gp1_Ques(struct perg *p)
{
   FILE *f; //apontador para ficheiro
   f=fopen("gp1.dat", "r"); //abertura do ficheiro
   char buf[5];
int reg=0, qnum=0, random, op; //declaração variáveis
int qual, result; //declaração variáveis
rewind(f); //retorna a posição corrente do ficheiro para o início
srand(time(NULL)); //função random
while (fread(p,sizeof *p,1,f)==1) //ciclo de leitura da estrutura perg
{
 reg++; //variavel contadora de registos
}
if (reg<=0) //condição que verifica se existem registos
{
 printf ("Sem registos");
 printf ("Necessario ter registos para jogar...");
 return;
}
else
{
 printf ("TOTAL de perguntas : %d \n",reg); //conta as perguntas
 printf ("\nO seu score maximo sera    : %d\n",reg); //pontuação máxima do jogo
 qual = reg*(0.75); //contagem minima para passar de fase
 printf ("\nPara a qualificacao precisa de: %d\n",qual); //total minimo para passar fase
 //testes para ver se funciona o random
 random=rand()%reg; //função random
 printf("\n%d\n", random);
 reg = random; //atribui a variavel reg o valor de random
 printf("\n%d\n", reg);
}
printf("Quer comecar a jogar ?(Sim=1; Nao=0) \n");
fgets(buf, sizeof buf , stdin);
sscanf(buf, "%d", &op);
if (op==1)
{
 while(fread(p, sizeof *p, 1, f))
 {
	 reg++;
 if (p->id==reg) //condição que verifica de no ficheiro o id é = ao reg
 {
  printf("\nPergunta : %s", p->ques);
  printf("\nOpcao 1 : %s",p->op1);
  printf("\nOpcao 2 : %s",p->op2);
  printf("\nOpcao 3 : %s",p->op3);
  printf("\nOpcao 4 : %s",p->op4);
  }
  else
  {
	  printf("Registo nao existente");
  }
}
/*while (fread(p, sizeof *p,1, f)==1)
//{
 //printf("Utilizador ligado: %s",jogador);
 printf ("Resultado : %d",result);
 qnum++;
}*/
}
fclose(f);
}

Nem o registo aparece nem a frase Registo nao existente...por isso deve ser problema de chavetas, não??

Só não vejo é onde...

gmc11

 

Link to comment
Share on other sites

Obrigado

if (op==1)
{
	 while(fread(p, sizeof *p, 1, f))
	 {
			 reg++;
 if (p->id==reg) //condição que verifica de no ficheiro o id é = ao reg
 {
	  printf("\nPergunta : %s", p->ques);
	  printf("\nOpcao 1 : %s",p->op1);
	  printf("\nOpcao 2 : %s",p->op2);
	  printf("\nOpcao 3 : %s",p->op3);
	  printf("\nOpcao 4 : %s",p->op4);
	  }
	  else
	  {
			  printf("Registo nao existente");
	  }
}

Mas estás a dizer para usar em vez disso, ou seja usar a função fseek para posicionar no início e no fim?

gmc11

 

Link to comment
Share on other sites

sim, o bsscara disse que podes usar o fseek para colocar o ponteiro directamente no fim do ficheiro dizendo assim o seu tamanho.

com um tamanho fixo de elementos basta dividires o valor pelo tamanho fixo e teras o número de elementos.

depois é só multiplicares o número da resposta que pretendes pelo tamanho fixo para obteres a posição do ficheiro da resposta pretendida. voltas a o fseek para ir directamente para a posição pretendida.

nota:

int reg=0, qnum=0, random, op;
...
while (fread(p,sizeof *p,1,f)==1) {
 reg++;
}
if (reg<=0) {

A variável reg só terá um valor negativo quando leres MAX_INT + 1 elementos do ficheiro (olha que são mesmo muitos). basta um == 😄

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Obrigado

Tenho é um problema, o último if não me entra

Pus uns printf pelo caminho a ver se chegava lá mas não chega

if (op==1)
{
 printf("escolheu o sim");
 fseek(f,0,SEEK_END);
 reg = ftell(f) / sizeof *p;
 fseek(f,0,SEEK_SET);
 printf("Valor de reg %d", reg);
 if (p->id==reg) //condição que verifica de no ficheiro o id é = ao reg
 {

A frase aparece-me, ponho a opção 1 e termina o programa...

Está alguma mal aqui?

Edited by alphasil
gmc11

 

Link to comment
Share on other sites

Era um problema do fgets, já está resolvido.

A questão é esta, já tenho os valores contados, já tenho o random, já atribui ao novo valor de reg o valor de random, agora quero que vá buscar o id respetivo, por isso não vejo relevância em voltar a contar os registos, percebes?

Já tenho isso aqui.

printf ("TOTAL de perguntas : %d \n",reg); //conta as perguntas
	 printf ("\nO seu score maximo sera    : %d\n",reg); //pontuação máxima do jogo
	 qual = reg*(0.75); //contagem minima para passar de fase
	 printf ("\nPara a qualificacao precisa de: %d\n",qual); //total minimo para passar fase
	 //testes para ver se funciona o random
	 random=rand()%reg; //função random
 printf("\n%d\n", random);
 reg = random; //atribui a variavel reg o valor de random
 printf("\n%d\n", reg);

Como já tenho o novo reg atribuido pelo random, agora é só chamar o registo respetivo, estou a ir bem?

gmc11

 

Link to comment
Share on other sites

if (op==1)
{
 printf("escolheu o sim");
 fseek(f,0,SEEK_END);
 reg = ftell(f) / sizeof *p;
 fseek(f,0,SEEK_SET);
 printf("Valor de reg %d", reg);
 if (p->id==reg) //condição que verifica de no ficheiro o id é = ao reg
 {

A frase aparece-me, ponho a opção 1 e termina o programa...

Está alguma mal aqui?

Está, o que o HHH te disse foi para usares o fseek para posicionares o cursor da stream no registo pretendido, não para usar o código que te dei que serve para obter o número de registos no ficheiro. O código que te dei é para usar em vez do que tens a contar registos, no início da função. Portanto no ponto que referes no teu código acima deves fazer 'fseek(f, reg * sizeof *p, SEEK_SET)' e depois fread(...) para ler o registo.

Link to comment
Share on other sites

lol

Pois, obrigado, já estava a ver qual era a utilidade de contar 2 vezes os registos....

Vou tentar seguir esse raciocínio

Então, percebendo bem o que te estavas a referir, posso contar logo os registos com o fseek e atribuir a variável reg o total, deste modo simplifica mais.

gmc11

 

Link to comment
Share on other sites

Pelos vistos já está a funcionar, vai-me buscar o registo dado pelo random.

A vossa opinião final se faz favor:

//Gestão jogo para grupo 1
void gp1_Ques(struct perg *p)
{
   FILE *f; //apontador para ficheiro
   f=fopen("gp1.dat", "r"); //abertura do ficheiro
   char buf[5];
int reg=0, qnum=0, random, op; //declaração variáveis
int qual, result; //declaração variáveis
rewind(f); //retorna a posição corrente do ficheiro para o início
srand(time(NULL)); //função random
fseek(f, 0, SEEK_END);
reg=ftell(f) /sizeof *p;
fseek(f, 0 , SEEK_SET);
if (reg<=0) //condição que verifica se existem registos
{
 printf ("Sem registos");
 printf ("Necessario ter registos para jogar...");
 return;
}
else
{
 printf ("TOTAL de perguntas : %d \n",reg); //conta as perguntas
 printf ("\nO seu score maximo sera    : %d\n",reg); //pontuação máxima do jogo
 qual = reg*(0.75); //contagem minima para passar de fase
 printf ("\nPara a qualificacao precisa de: %d\n",qual); //total minimo para passar fase
 //testes para ver se funciona o random
 random=rand()%reg; //função random
 reg = random; //atribui a variavel reg o valor de random
}
   printf("\nQuer comecar a jogar ?(Sim=1; Nao=0) \n");
   scanf("%d", &op);
   if(op==1)
   {
    fseek(f, reg * sizeof *p, SEEK_SET);
    fread(p, sizeof *p, 1, f);
    printf("\nPergunta : %s", p->ques);
    printf("\nOpcao 1 : %s",p->op1);
    printf("\nOpcao 2 : %s",p->op2);
    printf("\nOpcao 3 : %s",p->op3);
    printf("\nOpcao 4 : %s",p->op4);
   }
fclose(f);
}

Podia ficar melhor, mais simples, mais eficaz?'

cumps

Obrigado

gmc11

 

Link to comment
Share on other sites

notas para uma melhor programação :

1º - declara à cabeça todas a variáevis (tens um fopen lá pelo meio)

2º - a indentação está +- (pode ser do geshi ... não sei)

3º - separa sempre o código de manipulação de dados do código de apresentação de informação (tens tudo na mesma função)

4º - estás a atribuir o valor aleatório para a variável "reg", desta forma estás a perder a informação de quantas perguntas existem no ficheiro

5º - o processo de abertura e verificação de número de registo devia ser efectuado no início da aplicação eliminando a necessidade de verificação continua

6º - a abertura de ficheiro, o seu manuseamento e fecho deverá ser o mais rápido possível, isto implica saberes à partida o que pretendes do ficheiro para poder chamar a função fclose o mais cedo possível (por isso o ponto 5)

assim de cabeça é isso ... pode ser que me lembre e alguma coisa mais tarde

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Obrigado mais uma vez

Ponto a ponto

1 - Já alterei o lugar do fopen, as variaveis estão todas em cima;

2- Deve ser do geshi (aqui está tudo certinho)

3- Criar uma função que vai chamar os resultados desta manipulação?

4- Criar uma outra variavel (reg1) que vai ser a do random sem mexer na principal que é onde está a contagem dos registos?

5 e 6 - Pôr o FILE *f como global?

Obrigado

gmc11

 

Link to comment
Share on other sites

3- Criar uma função que vai chamar os resultados desta manipulação?

o que estou a dizer é teres por exemplo ... um ficheiro .c com o código de manipulação de dados, outro para apresentação de menus e um terceiro só para o main

4- Criar uma outra variavel (reg1) que vai ser a do random sem mexer na principal que é onde está a contagem dos registos?

isso já é contigo ... era só um aviso ..

5 e 6 - Pôr o FILE *f como global?

epa ... quantas vezes já leste aqui para não usar variáveis globais ??

o que estou a dizer é, quando a aplicação arranca abres o ficheiro, vês quantas perguntas tem e fechas. Depois é só abrir, ler a pergunta e fechar novamente

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Já agora, enquanto estava a verificar uma função surgiu-me esta duvida

Se criar vários ficheiros, um para menus, outro para manipulação de ficheiros, a chamada deles para o main é só fazer

função()?

cumps

Edited by alphasil
gmc11

 

Link to comment
Share on other sites

Sim, mas vais ter de incluir um outro ficheiro (ficheiro de inclusão, com extensão .h) no código com o prótotipo da função (ou declará-lo à mão onde vai ser usada). Podes começar por aqui para perceber a utilização dos ficheiros de inclusão próprios.

Link to comment
Share on other sites

Oi

Já pus isso tudo em três ficheiros *.c main , menus e funcoes para além de ter posto um ficheiro *.h com com o protótipo das funçoes, está tudo a funcionar menos esta função que estoira sempre que escolho um (segmentation fault) quando estava num ficheiro único funcionava..

O meu ficheiro h

#ifndef FUNC_H_INCLUDED
#define FUNC_H_INCLUDED
//funções para a gestão das perguntas
void ad_perguntas();
void ver_perguntas();
void edit_perguntas();
void remov_perguntas();
void ad_perguntasgp2();
void ver_perguntasgp2();
void edit_perguntasgp2();
void remov_perguntasgp2();
void LeVetor();
void vetorOrdenado();
void bubbleSort();
void ad_perguntasgp4();
void ver_perguntasgp4();
void edit_perguntasgp4();
void remov_perguntasgp4();
//Funçoes de menus
void tipoMenu();
void menu_principal();
void menu_ad();
void menu_ad1();
void menu_ad2();
void menu_ad3();
//Função jogo
void jogo();
void gp1_Ques();
//registo jogaodres
void registo();
int login();
#endif // FUNC_H_INCLUDED

A função que estoira é esta

int login(struct jogador *u)
{
   char usr1[30], userpass[50];
   memset(usr1, 0, 30);
   memset(userpass, 0, 50);
   int op;
   struct jogador j;
   struct perg p;
   FILE *f;
   f=fopen("registos.dat", "r");
   if (!f)
   {
    printf("Nao existe este ficheiro");
   }
   fseek(f, 0, SEEK_END);
   fseek(f, 0, SEEK_SET);
   printf("\nPara jogar tem de estar registado...\n");
   printf("\nTem registo ? (1 - Sim / 2 - Nao) \n");
scanf(" %d", &op);
getchar();
   if(op==1)
   {
    fread(u, sizeof *u, 1, f);
    printf("Introduza o nick \n");
    fgets (usr1, 29, stdin);
    printf("Introduza a sua pass \n");
    fgets (userpass, 49, stdin);
    if (strcmp(usr1,u->nick)==0)
    {
	    if (strcmp(userpass, u->pass)==0)
		    {
			    gp1_Ques(&p);
		    }
    }
    else
    {
	    printf("Erro no nick ou na pass");
    }
   }
   if (op==2)
   {
    registo(&j);
   }
   return 0;
}

Arrebenta nesta linha quando uso o debug

fread(u, sizeof *u, 1, f);

Antes de pôr separado funcionava, não percebo por que razão funcionam todas menos esta..

Mestres, que fiz de mal, mais uma vez 😛

Obrigado

gmc11

 

Link to comment
Share on other sites

Bom dia;

Percebo mas por que razão dão todas menos essa??

Pus os protótipos iguais mas agora dá erro, não compila...tenho uma quantidade de warnings e erros.

Compiling: menus.c

In file included from D:\2012\c_exe\Projeto Final\menus.c:7:0:

D:\2012\c_exe\Projeto Final\/func.h:37:18: warning: 'struct jogador' declared inside parameter list [enabled by default]

D:\2012\c_exe\Projeto Final\/func.h:37:18: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]

D:\2012\c_exe\Projeto Final\menus.c: In function 'jogo':

D:\2012\c_exe\Projeto Final\menus.c:88:13: error: too few arguments to function 'login'

D:\2012\c_exe\Projeto Final\/func.h:37:5: note: declared here

Process terminated with status 1 (0 minutes, 0 seconds)

2 errors, 2 warnings

Só pus as funções iguais.

Pelo que percebo na função jogo, quando chamo a função login() espera argumentos dentro dos parêntesis, ou seja tenho de usar uma apontador para jogador?

cumps

gmc11

 

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
 Share

×
×
  • 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.