Ora funciona, ora não funciona... do{}while()

borntonag

Power Member
Boas!
Estou aqui a relembrar alguns princípios da programação em C, e estou com um pequeno problema. Uso o Dev-c++ 4.9.9.2
Como diz o título tenho um programa que tanto funciona quando faço "Compile & Run" como fica num loop infinito.

O objetivo do programa é simples:
Sortear 3 números entre 1 e 10 e guardá-los num vetor, mas só os imprimi se a soma dos 3 valores estiver dentro de um intervalo [3,12].

Código:
#include<stdio.h>

main(){
       int num[3], i, soma_num=0;
       
       srand(time(NULL));
       
       printf("\n\n");
       
       do{
          for(i=0;i<=2;i++)
          {
              num[i]= rand() % 10 + 1;
              printf(" Numero %d: %d ",i+1,num[i]);
              soma_num+=num[i];
          }
       }while(soma_num < 3 || soma_num > 12);

       printf("\n\n Soma numeros: %d ",soma_num);         

       getch();
}

SOLUÇÃO:
Código:
#include<stdio.h>

main(){
       int num[3], i, j, soma_num;
       
       srand(time(NULL));
       
       printf("\n\n");
       
       do{
          soma_num=0;
          for(i=0;i<=2;i++)
          {
              num[i]= rand() % 10 + 1;
              soma_num+=num[i];
          }
       }while(soma_num < 3 || soma_num > 12);

       for(j=0;j<=2;j++)
          {
              printf(" Numero %d: %d ",j+1,num[j]);
          }
       printf("\n\n Soma numeros: %d ",soma_num);         

       getch();
}
 
Última edição:
Não tás a meter o soma_num a zero no início do ciclo do. Sem isso o soma_num vai aumentando infinitamente e daí a condição não ficar verdadeira. (pelo menos até fazer overflow)
 
Não tás a meter o soma_num a zero no início do ciclo do. Sem isso o soma_num vai aumentando infinitamente e daí a condição não ficar verdadeira. (pelo menos até fazer overflow)

Código:
#include<stdio.h>
main(){
       int num[3], i, soma_num=0;
       
       srand(time(NULL));
       
       printf("\n\n");
       
       do{
          [COLOR=#0000cd]soma_num=0;[/COLOR]
          for(i=0;i<=2;i++)
          {
              num[i]= rand() % 10 + 1;
              printf(" Numero %d: %d ",i+1,num[i]);
              soma_num+=num[i];
          }
       }while(soma_num < 3 || soma_num > 12);

       printf("\n\n Soma numeros: %d ",soma_num);         

       getch();
}
Ali?
Ele assim está a imprimir números a mais, outras vezes funciona. Pelo que percebi ele continua a imprimir três números até aparecerem aqueles que somados ficam dentro do intervalo.
 
Isso é porque tens um printf dentro do ciclo, para o que queres tens que guardar os números dentro do ciclo e só os imprimir depois, tal como com o resultado.
 
Problema resolvido ("noobice" neste caso). (solução no 1º post)

Agora só me falta comparar os valores sorteados para que não sejam iguais entre si, isto é, num[0] != num[1] != num[2]
Se tiverem alguma ideia de como o fazer não se acanhem.

E mais uma questão: O código está "bem escrito" assim ou existe alguma maneira de o simplificar?

EDIT: Depois de conseguir fazer com que sorteie números não iguais, queria transformar este programinha numa função, sendo que ela não recebe valores nenhuns mas envia os números sorteados, ou seja, tenho de enviar o vector e na main fazer um ciclo para o imprimir correcto?
 
Última edição:
Agora só me falta comparar os valores sorteados para que não sejam iguais entre si, isto é, num[0] != num[1] != num[2]
Se tiverem alguma ideia de como o fazer não se acanhem.
Não compilei, mas será algo do género:
Código:
#include<stdio.h>

main(){
		int num[3], i, j, soma_num;
		srand(time(NULL));
		printf("\n\n");
		do {
			soma_num=0;
			for(i=0;i<=2;i++) {
				do {
					num[i]= rand() % 10 + 1;
					valid_number=true;
					for(j=0;j<i;j++)
						valid_number = valid_number && num[i] <> num[j];
				} while(!valid_number);
				soma_num+=num[i];
			}
		} while(soma_num < 3 || soma_num > 12);

		for(i=0;i<=2;i++)
			printf("Numero %d: %d\n",i+1,num[i]);
		printf("\n\n Soma numeros: %d ",soma_num);         

		getch();
}

Tambem podes preencher um array de 10 posições (visto ser numeros de 1 a 10), preenche-lo todo com 0's e sempre que gerares um número, verificas se a posição desse numero - 1 é 0.
Se for 0, é um número válido e preenches na posição n-1 com 1.
Se não, geras outro número e fazes a verificação outra vez.
 
Podias-me explicar o que isto faz?
Código:
valid_number = valid_number && num[i] <> num[j];

A outra sugestão também não percebi bem. Tem haver com os endereços em que os números são guardados é? Ou seja, o programa ia ver se já estava ocupada a posição de memória do número gerado é isso ou não tem nada haver?
Fiquei com um nó... :-D
 
Depois de algum tempo sem pegar nisto, voltei a praticar um pouco a minha programação, mas estou a ter algumas dificuldades.

Não compilei, mas será algo do género:
Código:
#include<stdio.h>

main(){
        int num[3], i, j, soma_num;
        srand(time(NULL));
        printf("\n\n");
        do {
            soma_num=0;
            for(i=0;i<=2;i++) {
                do {
                    num[i]= rand() % 10 + 1;
                    valid_number=true;
                    for(j=0;j<i;j++)
                        valid_number = valid_number && num[i] <> num[j];
                } while(!valid_number);
                soma_num+=num[i];
            }
        } while(soma_num < 3 || soma_num > 12);

        for(i=0;i<=2;i++)
            printf("Numero %d: %d\n",i+1,num[i]);
        printf("\n\n Soma numeros: %d ",soma_num);         

        getch();
}
Não percebi muito bem esta solução, é necessário inicializar as variáveis 'valid_number' e 'true', pode-se igualar ambas a 0?

Tambem podes preencher um array de 10 posições (visto ser numeros de 1 a 10), preenche-lo todo com 0's e sempre que gerares um número, verificas se a posição desse numero - 1 é 0.
Se for 0, é um número válido e preenches na posição n-1 com 1.
Se não, geras outro número e fazes a verificação outra vez.
Com este código não estou só a verificar o anterior?

Entretanto já desenvolvi um programa dentro do mesmo modo de funcionamento mas um pouco maior.
Basicamente isto é um euromilhões em que bate tudo certo, mas para ficar perfeito ele deveria comparar os números que são gerados com os anteriores para não haver números ou estrelas iguais entre si.
Código:
main(){
       char op;
       int num[5], est[2], num_ch, i, ii, j, jj, k, rand_num, soma_num, soma_est;
       
       srand(time(NULL));
       
       op=menu();
       
       switch(op){
                  case '1':
                       system("cls");
                       printf("\n Numero de chaves: ");
                       scanf("%d",&num_ch);
                       for(k=1 ; k<=num_ch ; k=k+1)
                               {
                                    printf("\n\n");
                                    
                                    //Sorteio números
                                    do{
                                       soma_num=0;
                                       for(i=0;i<=4;i++)
                                       {
                                           num[i]= rand() % 50 + 1;
                                           soma_num+=num[i];
                                       }
                                       }while(soma_num < NMIN || soma_num > NMAX);
                                    
                                    //Sorteio estrelas    
                                    do{
                                       soma_est=0;
                                       for(ii=0;ii<=1;ii++)
                                       {
                                           est[ii]= rand() % 11 + 1;
                                           soma_est+=est[ii];
                                       }
                                       }while(soma_est < EMIN || soma_est > EMAX);

                                    for(jj=0;jj<=4;jj++)
                                    {
                                       printf(" %d ",num[jj]);
                                    }
                                    
                                    printf(" * ");
                                    
                                    for(jj=0;jj<=1;jj++)
                                    {
                                       printf(" %d ",est[jj]);
                                    }
                                       
                                    printf("\n\n Soma numeros: %d ",soma_num);
                                    printf("\n\n Soma numeros: %d ",soma_est);       
                               } 
                       break;
                  case '2':
                       return 0;
                  default :
                       system("cls");
                       printf("\n\n Escolha uma opcao valida!");
                  }
 
Back
Topo