Jump to content

Recommended Posts

Posted

Oi ppl

Mais um problema 🙂

Tenho este código para registar jogadores

void registo(struct jogador *j)
{
   FILE *f;
   char usr [100];
   int nregistos, flag =0;
   f=fopen("registos.dat", "a+b");
   if(f==NULL)
   {
       printf("Erro ao abrir ficheiro.");
   }
   else
   {
       while (fread(j,sizeof(struct jogador),1,f)==1)
       {
           nregistos++;
           }
       printf("Registo de jogadores \n");
       printf("\nIntroduza o seu nome \n");
       fgets(j->nome, 100, stdin);
       printf("Introduza o seu nickname \n");
       fgets(j->nick, 100, stdin);
       while(fread(j, sizeof *j, 1, f)==1)
       {
           flag=0;
           if (strcmp(usr,j->nick)==0)
           {
               flag = 1;
               break;
           }
           }
       if (flag==1 || strlen(usr)<2)
       {
           printf("Este nick ja esta em uso...\n");
           printf("Escolha agora outro...\n");
           fgets(j->nick, 50, stdin);
       }
       printf("Introduza a sua pass \n");
       fgets(j->pass, 100, stdin);
       fseek(f,0,SEEK_END);
       fwrite (&j,sizeof(struct jogador),1,f);
   }
    fclose(f);
}

A estrutura é essa

struct jogador	 /* Estrutura Utilizadores */
{
 char nome[100];
 char nick[100];
 char pass[100];
 int log;
};

Quando entro na função acima, crasha e dá erro "Segmentation fault", o que é isso?

cumps

gmc11

 

  • Replies 40
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted

Segmentation fault significa que estás a dereferenciar um ponteiro que não é válido; aponta para uma zona qualquer de memória que não pertence ao processo ou é um ponteiro nulo (que também nunca é válido para um processo).

Provavelmente não estás a inicializar o ponteiro que passas à função.

Posted

dando segmentation fault ou não, sabes que o teu código é extremamente lento por estares a trabalhares em ficheiros e não em memória certo ??

alem disso, após a leitura inicial do ficheiro onde determinas o número de jogadores, apesar de existir uma formula muito mais simples para esse cálculo (tamanho do ficheiro / tamanho da estrutura) não fazes reset do ponteiro interno do ficheiro, o segundo while falha sempre na primeira operação de leitura

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

dando segmentation fault ou não, sabes que o teu código é extremamente lento por estares a trabalhares em ficheiros e não em memória certo ??

Sim, eu sei, mas é a unica forma de manter registo das perguntas e jogadores.

alem disso, após a leitura inicial do ficheiro onde determinas o número de jogadores, apesar de existir uma formula muito mais simples para esse cálculo (tamanho do ficheiro / tamanho da estrutura) não fazes reset do ponteiro interno do ficheiro, o segundo while falha sempre na primeira operação de leitura

não percebi essa parte, o meu primeiro while está errado?

Depois de aparecer "Introduza o seu nome".....crash

Edited by alphasil
gmc11

 

Posted

Sim, eu sei, mas é a unica forma de manter registo das perguntas e jogadores.

não, não é

é melhor ler tudo para uma lista em memória do que estar constantemente a ler do ficheiro

não percebi essa parte, o meu primeiro while está errado?

o que eu disse não é o que primeiro while que esteja errado, nem o segundo !!!

é que não fazes o rewind do ponteiro interno do ficheiro logo no segundo while a função fread vai sempre falhar !!!

Depois de aparecer "Introduza o seu nome".....crash

se crash'a ao ler para o elemento da estrutura é porque o ponteiro passado para a função registo não deverá estar correcto

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

O problema está nos fgets.

Desativei-os todos e correu o código todo.

Agora o que acho estranho é que mesmo não escrevendo nada crash'a com fgets, por que razão será??

Com o debug dá erro aqui

while(fread(j, sizeof *j, 1, f)==1)

o 1º

Edited by alphasil
gmc11

 

Posted

Então vamos por partes que já estou a ficar meio cego com isto.

A estrutura existe e chama-se jogador

na funçao registo uso (struct jogador *j)

já estou a chamara a estrutura certo?

while(fread(j, sizeof *j, 1, f)==1)

uso *j para apontar para a estrutura

uso of fgets(j->nome, tamanho (100), stdin);

falta-me alguma coisa?' Sinceramente não estou a ver

gmc11

 

Posted

Não me acredito....

Tive de ir ao menu jogo e pôr

struct jogador p

e ao chamar a função registo pôr

registo(&p)

Agora não está a dar o segmentation fault

mas salta as duas primeiras perguntas...

printf("\nIntroduza o seu nome \n");
fgets(p->nome, 100, stdin);
printf("Introduza o seu nickname \n");

aparece-me 2 seguidas, tenho alguma coisa mal??

gmc11

 

Posted

"se crash'a ao ler para o elemento da estrutura é porque o ponteiro passado para a função registo não deverá estar correcto"

qual foi a parte do post que não percebeste ?

a parte de "ponteiro passado para a função registo" ou o "não deverá estar correcto" ???

é o que dá ignorar os post das pessoas ...

se está a saltar o fgets é porque o buffer de leitura não se encontra vazio .. muito provavelmente lixo deixado no momento da leitura da opção do menu

1ª opção : limpa o buffer de leitura

1ª opção : corrige o código de leitura de opção do menu

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

"se crash'a ao ler para o elemento da estrutura é porque o ponteiro passado para a função registo não deverá estar correcto"

qual foi a parte do post que não percebeste ?

a parte de "ponteiro passado para a função registo" ou o "não deverá estar correcto" ???

é o que dá ignorar os post das pessoas ...

Sim...agora percebi, não estava a ver o porquê, isso dos ponteiros mata-me....lol

Isso dos ponteiros é muito confuso para mim, já li e reli e não entra.

Ja pus fflus(stdin) e já dá

Agora há um erro estranho

ponho um user e diz-me que já existe, pede para pôr outro, ponho o mesmo e aceita...lol

while (fread(p,sizeof *p,1,f)==1)
	{
		if (strcmp(usr, p->nick)== 0) // A função strcmp() compara a usr com a p->nick da estrutura jogador
		{
			flag = 1;
			break;
		}
	}
	if (flag==1 || strlen(usr)<2) //strlen comprimento da string fornecida
	{
		printf("Este nick ja esta em uso...\n");
		printf("Escolha agora outro...\n");
		fgets(p->nick, 50, stdin);
	}
	printf("Introduza a sua pass \n");
	fgets(p->pass, 100, stdin);
	fwrite (p,sizeof *p,1,f);

Tenho os comentários nos sítios...há algo que me está a fazer confusão

se são iguais devolve 0, deve ler o ficheiro para ver se este p->nick existe, pelos vistos compara diretamente, acho eu...está alguma coisa mal

Obrigado pela ajuda, e acredita, não é não querer fazer o que vocês dizem nos posts, mas às vezes não sei do que estão a falar... 😄

Edited by Baderous
geshi
gmc11

 

Posted (edited)

Aí vai

Já corrigi um pequeno erro mas mesmo assim deixa escrever o mesmo nick 2 vezes

void registo(struct jogador *p)  //char nick //char id
{
FILE *f;
char usr [100];
fflush(stdin);
int nregistos, flag =0;
f=fopen("registos.dat", "a+b");
if(f==NULL)
{
	printf("Erro ao abrir ficheiro.");
}
else
{
	while (fread(p,sizeof *p,1,f)==1)
	{
		nregistos++;
	}
	printf("Registo de jogadores \n");
	printf("\nIntroduza o seu nome \n");
	fgets(p->nome, 100, stdin);
	printf("\nIntroduza o seu nickname \n");
	fgets(usr, 100, stdin);
	while (fread(p,sizeof *p,1,f)==1)
	{
		if (strcmp(usr, p->nick)== 0) // A função strcmp() compara a usr com a p->nick da estrutura jogador
		{
			flag = 1;
			break;
		}
	}
	if (flag==1 || strlen(usr)<2) //strlen comprimento da string fornecida
	{
		printf("Este nick ja esta em uso...\n");
		printf("Escolha agora outro...\n");
		fgets(p->nick, 50, stdin);
	}
	printf("Introduza a sua pass \n");
	fgets(p->pass, 100, stdin);
	strcpy(p->nick,usr); //A função strcpy() copia a string-origem para a string- destino
	fwrite (p,sizeof *p,1,f);
}
 fclose(f);
}

o que estava mal inicialmente era

fgets(p->nick, 100, stdin);

mudei

fgets(usr, 100, stdin);

e só depois tem lógica serem comparados com o strcmp()

Mas faço outro registo e deixa pôr o mesmo nick e não deveria..

Edited by Baderous
geshi
gmc11

 

Posted (edited)

o que eu disse não é o que primeiro while que esteja errado, nem o segundo !!!

é que não fazes o rewind do ponteiro interno do ficheiro, logo, no segundo while a função fread vai sempre falhar !!!

Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

Já está a dar, muito obrigado amigo.

O código final é este, se alguém quiser aproveitar.

void registo(struct jogador *p)  //char nick //char id
{
FILE *f;
char usr [100];
fflush(stdin);
int nregistos, flag =0;
f=fopen("registos.dat", "a+b");
if(f==NULL)
{
	printf("Erro ao abrir ficheiro.");
}
else
{
	while (fread(p,sizeof *p,1,f)==1)
	{
		nregistos++;
	}
	printf("Registo de jogadores \n");
	printf("\nIntroduza o seu nome \n");
	fgets(p->nome, 100, stdin);
	printf("\nIntroduza o seu nickname \n");
	fgets(usr, 100, stdin);
	rewind(f);
	while (fread(p,sizeof *p,1,f)==1)
	{
		if (strcmp(usr, p->nick)== 0) // A função strcmp() compara a usr com a p->nick da estrutura jogador
		{
			flag = 1;
			break;
		}
	}
	if (flag==1 || strlen(usr)<2) //strlen comprimento da string fornecida
	{
		printf("Este nick ja esta em uso...\n");
		printf("Escolha agora outro...\n");
		fgets(p->nick, 50, stdin);
	}
	printf("Introduza a sua pass \n");
	fgets(p->pass, 100, stdin);
	strcpy(p->nick,usr); //A função strcpy() copia a string-origem para a string- destino
	fwrite (p,sizeof *p,1,f);
}
 fclose(f);
}

Mudavas alguma coisa??

Edited by Baderous
geshi
gmc11

 

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.