Megasena melhorar código [RESOLVIDO]

1. Megasena melhorar código [RESOLVIDO]

Marco Brainiac
mbrainiac

(usa Debian)

Enviado em 01/10/2015 - 11:26h

Caros amigos,

cada vez que dou s (sim) aparece 2 vezes como corrijo?
O n (não) parece perfeito.
Dezena 1 é 42
Dezena 2 é 4
Dezena 3 é 33
Dezena 4 é 27
Dezena 5 é 26
Dezena 6 é 50
Quer Mostrar mais dezenas (s/n)?
s
Dezena 1 é 32
Dezena 2 é 30
Dezena 3 é 17
Dezena 4 é 59
Dezena 5 é 13
Dezena 6 é 1
Quer Mostrar mais dezenas (s/n)?
Dezena 1 é 32
Dezena 2 é 30
Dezena 3 é 17
Dezena 4 é 59
Dezena 5 é 13
Dezena 6 é 1
Quer Mostrar mais dezenas (s/n)?
s
Dezena 1 é 44
Dezena 2 é 33
Dezena 3 é 33
Dezena 4 é 52
Dezena 5 é 51
Dezena 6 é 29
Quer Mostrar mais dezenas (s/n)?
Dezena 1 é 44
Dezena 2 é 33
Dezena 3 é 33
Dezena 4 é 52
Dezena 5 é 51
Dezena 6 é 29
Quer Mostrar mais dezenas (s/n)?
s
Dezena 1 é 56
Dezena 2 é 37
Dezena 3 é 2
Dezena 4 é 53
Dezena 5 é 49
Dezena 6 é 52
Quer Mostrar mais dezenas (s/n)?
Dezena 1 é 56
Dezena 2 é 37
Dezena 3 é 2
Dezena 4 é 53
Dezena 5 é 49
Dezena 6 é 52
Quer Mostrar mais dezenas (s/n)?
n
mbrainiac@hotpc:~/Área de trabalho/C_programas$


#include<stdio.h>
#include<stdlib.h>
#include <time.h>

int main(){
int x,a;
char perg ;

while(perg != 'n')
{

srand( (unsigned)time(NULL) );
for(a=1;a <= 6; a++)
{

x = 1 + (rand()%60 ); // Receber valor entre 1 e 60
printf("Dezena %d é %d \n",a, x);

}
printf("Quer Mostrar mais dezenas (s/n)?\n");
scanf("%c",&perg);

}

return 0;
}



  


2. MELHOR RESPOSTA

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 01/10/2015 - 11:41h

Opa amigo.

Vou fazer algumas observações:

1. O srand é recomendável ser chamado apenas 1 vez no Main, e em fora de Loops;

2. Você utiliza o variável 'perg' sem inicializar ela. Pode ser que em alguma execução ela comece com o valor 'n', por isso é recomendável declarar e já inicializar essa variável.

3. For: Não é muito recomendável inicializar variáveis com valor 1 e utilizar o operador <=. Nesses casos é recomendável utilizar o for nesse estilo: for(a=0;a < 6; a++) E depois utilizar a variável como a+1, nesse caso. Agora você talvez não deva entender muito bem o motívo, mas quando for aprender vetores, eles começam em 0 e vão até n-1 (ou seja, se o vetor tem 6 posições, vai de 0 até 5).

Agora respondendo a sua pergunta: Pq não funciona?

Por causa de um 'problema' chamado lixo de buffer.

Uma maneira mais rápida de resolver agora (e não muito recomendável) é colocar um espaço antes do %c, ou seja, scanf(" %c",&perg);

Espero ter ajudado

Se ajudei, marque o tópico como resolvido e clique em melhor resposta.

[]'s

T+

--

body@human: $ sudo su
brain@human: # apt-get purge -y windows* && echo "Windows removed successfully"



3. Re: Megasena melhorar código

Perfil removido
removido

(usa Nenhuma)

Enviado em 01/10/2015 - 11:49h

Além das observações acima, talvez possa ser o seu "Enter" que também está sendo lido pelo scanf;
quando você pressiona "s" e em seguida dá um "Enter", você está enviando ao scanf dois chars, e não apenas um (que é a quantidade que a variável do tipo Ch consegue armazenar);

Adicionando as seguintes linhas no seu código resolve seu problema:

char esc;
scanf("%c",&esc);


O código final fica assim:

#include<stdio.h>
#include<stdlib.h>
#include <time.h>

int main(){
int x,a;
char perg ;
char esc;

while(perg != 'n')
{

srand( (unsigned)time(NULL) );
for(a=1;a <= 6; a++)
{

x = 1 + (rand()%60 ); // Receber valor entre 1 e 60
printf("Dezena %d é %d \n",a, x);

}
printf("Quer Mostrar mais dezenas (s/n)?\n");
scanf("%c",&perg);
scanf("%c",&esc);

}

return 0;
}



Eu fiz o teste aqui e funcionou; só não sei se esse ainda é o melhor jeito;


4. Re: Megasena melhorar código [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 01/10/2015 - 11:54h


Uma maneira mais rápida de resolver agora (e não muito recomendável) é colocar um espaço antes do %c, ou seja, scanf(" %c",&perg);


Thihup, só uma pergunta: o que que o espaço antes do %c faz exatamente? e porque não é muito recomendável?
Eu não conheço esse "truque"; obrigado pela atenção e agradeço desde já!


5. Re: Megasena melhorar código [RESOLVIDO]

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 01/10/2015 - 12:09h

Olha, o espaço antes do %c limpa os caracteres como o \n, espaço e outros do buffer.

Mas como o Paulo já me explicou uma vez, vá que no buffer fique um caractere como o ÿ no buffer, o scanf iria entender como se fosse um caractere "de letra" (e e assim zuar todo o código.

Mas se for para coisa pequena e só corrigir tem a dica do espaço no scanf e também colocar um getchar() depois do scanf.

As duas não são praticas recomendável. Mas para resolver rapidamente (Leia-se POG) pode ser utilizado isso.

Espero ter ajudado

[]'s

T+

--

body@human: $ sudo su
brain@human: # apt-get purge -y windows* && echo "Windows removed successfully"




6. Re: Megasena melhorar código

Perfil removido
removido

(usa Nenhuma)

Enviado em 01/10/2015 - 12:21h

Entendi, obrigado!

Uma vez eu estava tendo um problema parecido com esse que o mbrainiac postou e, eu tinha visto em um lugar que tem uma função que consegue limpar da variável qualquer caractere que tivesse nela;
A função era mais ou menos assim: você entrava com a variável que queria passar o "filtro" (só não me lembro se funcionava tanto para char como para string ou só uma das duas) e, em seguida, dizia qual caractere queria tirar da variável (no caso, o "\n") - só que não me lembro de quase nada sobre, já que nunca mais precisei usá-la e me acostumei com esse truque do Ch


7. Re: Megasena melhorar código [RESOLVIDO]

Marco Brainiac
mbrainiac

(usa Debian)

Enviado em 01/10/2015 - 15:22h

unnslacker escreveu:

Entendi, obrigado!

Uma vez eu estava tendo um problema parecido com esse que o mbrainiac postou e, eu tinha visto em um lugar que tem uma função que consegue limpar da variável qualquer caractere que tivesse nela;
A função era mais ou menos assim: você entrava com a variável que queria passar o "filtro" (só não me lembro se funcionava tanto para char como para string ou só uma das duas) e, em seguida, dizia qual caractere queria tirar da variável (no caso, o "\n") - só que não me lembro de quase nada sobre, já que nunca mais precisei usá-la e me acostumei com esse truque do Ch

---
~$ seq -f '4/%g' 1 2 99999 | paste -sd-+ | bc -l



Olá,

Aqui explica formas de resolver, aque foi pasada pelo amigo e :
http://www.cprogressivo.net/2012/12/Buffer--o-que-e-como-limpar-e-as-funcoes-fflush-e-fpurge.html
Para limpar o buffer em Windows, use: fflush(stdin)
Para limpar o buffer em Linux, use: __fpurge(stdin)






8. Re: Megasena melhorar código [RESOLVIDO]

Marco Brainiac
mbrainiac

(usa Debian)

Enviado em 01/10/2015 - 15:29h

Agradeço aos amigos pela ajuda e atenção.

colocando espaço noscanf(" %c",&perg) como o Thihup mostrou;
#include<stdio.h>
#include<stdlib.h>
#include <time.h>

int main(){
int x,a;
char perg = 's' ;

while(perg != 'n')
{

srand( (unsigned)time(NULL) );
for(a=1;a <= 6; a++)
{

x = 1 + (rand()%60 ); // Receber valor entre 1 e 60
printf("Dezena %d é %d \n",a, x);

}
printf("Quer Mostrar mais dezenas (s/n)?\n");
scanf(" %c",&perg); // limpar buffer com espaço antes do %c



}

return 0;
}

Ou adicionando as instruções
fflush(stdin); // windows
__fpurge(stdin);// linux
abaixo do scanf:

#include<stdio.h>
#include<stdlib.h>
#include <time.h>

int main(){
int x,a;
char perg = 's' ;

while(perg != 'n')
{

srand( (unsigned)time(NULL) );
for(a=1;a <= 6; a++)
{

x = 1 + (rand()%60 ); // Receber valor entre 1 e 60
printf("Dezena %d é %d \n",a, x);

}
printf("Quer Mostrar mais dezenas (s/n)?\n");
scanf("%c",&perg); // limpar buffer com espaço antes do %c

fflush(stdin); // windows
__fpurge(stdin);// linux

}

return 0;
}



Ambas produzem as saídas:

mbrainiac@hotpc:~/Área de trabalho/C_programas$ ./megasena.x
Dezena 1 é 24
Dezena 2 é 59
Dezena 3 é 4
Dezena 4 é 52
Dezena 5 é 21
Dezena 6 é 28
Quer Mostrar mais dezenas (s/n)?
s
Dezena 1 é 12
Dezena 2 é 8
Dezena 3 é 22
Dezena 4 é 53
Dezena 5 é 6
Dezena 6 é 52
Quer Mostrar mais dezenas (s/n)?
s
Dezena 1 é 26
Dezena 2 é 59
Dezena 3 é 7
Dezena 4 é 13
Dezena 5 é 14
Dezena 6 é 34
Quer Mostrar mais dezenas (s/n)?
n
mbrainiac@hotpc:~/Área de trabalho/C_programas$


9. Re: Megasena melhorar código [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/10/2015 - 16:26h

Como eu sempre digo, scanf[i]() é possivelmente a mais complexa função da biblioteca padrão do C, porque ela não é apenas uma função que lê dados, mas sim uma função que tenta identificar padrões de texto a partir de um texto de entrada. Parte desses padrões pode ser fixa, parte pode ter tamanho variável, o padrão percebido pode ser guardado numa posição de memória indicada, mas também se pode usar a mesma regra para identificar um tipo de padrão (por exemplo: “%d”, que identifica um número inteiro), mas suprimir o armazenamento do valor correspondente (com “%*d”, por exemplo). Pode-se também especificar uma largura máxima para certas conversões de dados, bem como contar a quantidade de caracteres lidos até o momento, e possivelmente mais um monte de coisa de que não lembro agora.

Vale muito a pena parar para ler uma boa documentação de [i]scanf
() antes de se tentar usá-la a fundo -- ou mesmo nem tão a fundo assim. A documentação que vem com o Linux, por sinal, é muito boa.

No caso do seu programa, eis algumas mudanças que eu faria:

    - mudar o laço de repetição de while (executa zero ou mais vezes, pois testa a condição antes de começar a primeira iteração) para do...while (executa pelo menos uma vez, e testa a condição de repetição apenas no final de cada iteração);

    - mudar o nome da variável perg para resposta (ou abreviação), pois o que ela guarda é uma resposta, não uma pergunta;

    - tirar o srand() de dentro do laço de repetição, como já foi dito;

    - eventualmente colocar uma forma de garantir a não ocorrência de dezenas repetidas.

Eis uma forma didática de fazer a pergunta acerca de um novo sorteio.

/* Pergunta se quer repetir a execução */
while(1){
int resp;
printf("Quer sortear as dezenas novamente (S/N)? ");
resp=getchar();

if(resp==EOF){
fprintf(stderr, "Fim de entrada, encerrando o programa.\n");
exit(1); /* Sai sinalizando erro. */
}

if(resp!='\n') /* Se o usuário não digitou só Enter... */
scanf("%*[^\n]%*1[\n]"); /* ... suprime os caracteres até o fim da linha. */

if(resp=='n' || resp=='N')
exit(0); /* Sai sinalizando sucesso */

if(resp!='s' && resp!='S'){
fprintf(stderr, "Por favor, responda somente conforme as instruções.\n";
}
}


Note, porém, que o código acima, embora rejeite como respostas uma linha vazia e coisas que não comecem nem com S nem com N, aceita coisas como "Não quero mais o PT no governo, mesmo que o Temer tenha de assumir e o Cunha seja o segundo homem da República." do mesmo modo que aceitaria um simples "n" ou "N". Se você quiser impedir isso, teria de modificar o tratamento do resto da linha.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts