alphasil Posted May 28, 2012 at 07:37 PM Report #458650 Posted May 28, 2012 at 07:37 PM 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 Â
bsccara Posted May 28, 2012 at 08:07 PM Report #458657 Posted May 28, 2012 at 08:07 PM 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.
HappyHippyHippo Posted May 28, 2012 at 08:21 PM Report #458659 Posted May 28, 2012 at 08:21 PM 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 Portugol Plus
alphasil Posted May 28, 2012 at 08:27 PM Author Report #458664 Posted May 28, 2012 at 08:27 PM (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 May 28, 2012 at 08:31 PM by alphasil gmc11 Â
HappyHippyHippo Posted May 28, 2012 at 08:41 PM Report #458670 Posted May 28, 2012 at 08:41 PM 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 Portugol Plus
alphasil Posted May 28, 2012 at 08:43 PM Author Report #458673 Posted May 28, 2012 at 08:43 PM vou tentar corrigir...já volto a dar novidades. Obrigado gmc11 Â
alphasil Posted May 28, 2012 at 09:01 PM Author Report #458679 Posted May 28, 2012 at 09:01 PM (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 May 28, 2012 at 09:07 PM by alphasil gmc11 Â
HappyHippyHippo Posted May 28, 2012 at 09:06 PM Report #458682 Posted May 28, 2012 at 09:06 PM 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 Portugol Plus
alphasil Posted May 28, 2012 at 09:13 PM Author Report #458685 Posted May 28, 2012 at 09:13 PM 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 Â
alphasil Posted May 28, 2012 at 09:42 PM Author Report #458702 Posted May 28, 2012 at 09:42 PM 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 Â
HappyHippyHippo Posted May 28, 2012 at 10:06 PM Report #458712 Posted May 28, 2012 at 10:06 PM "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 Portugol Plus
alphasil Posted May 28, 2012 at 10:26 PM Author Report #458718 Posted May 28, 2012 at 10:26 PM (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 May 28, 2012 at 10:46 PM by Baderous geshi gmc11 Â
HappyHippyHippo Posted May 28, 2012 at 10:34 PM Report #458719 Posted May 28, 2012 at 10:34 PM faz post de todo o código da função IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
alphasil Posted May 28, 2012 at 10:38 PM Author Report #458720 Posted May 28, 2012 at 10:38 PM (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 May 28, 2012 at 10:46 PM by Baderous geshi gmc11 Â
HappyHippyHippo Posted May 28, 2012 at 10:43 PM Report #458722 Posted May 28, 2012 at 10:43 PM (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 May 28, 2012 at 10:43 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
alphasil Posted May 28, 2012 at 10:46 PM Author Report #458725 Posted May 28, 2012 at 10:46 PM Então antes do segundo while faço rewind(f); ? gmc11 Â
HappyHippyHippo Posted May 28, 2012 at 10:49 PM Report #458726 Posted May 28, 2012 at 10:49 PM não sei se essa função é suportada em todo lado .. se tivesse aqui o pmg ele dizia. no entanto sei que a seguinte é fseek(file, 0L, SEEK_SET); IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
alphasil Posted May 28, 2012 at 10:51 PM Author Report #458727 Posted May 28, 2012 at 10:51 PM (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 May 28, 2012 at 10:53 PM by Baderous geshi gmc11 Â
Baderous Posted May 28, 2012 at 10:54 PM Report #458728 Posted May 28, 2012 at 10:54 PM Começa a usar o GeSHi para postar código.
alphasil Posted May 28, 2012 at 11:00 PM Author Report #458732 Posted May 28, 2012 at 11:00 PM Não perebo...eu escolho a tag código...e ponho o código dentro, estranho acrescentei a linha fseek(f, 0, SEEK_END); gmc11 Â
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now