Saída while encerrar programa não funciona

27 respostas
D

Prazer a todos.
O código está certo, mas a saída do while para sair do programa não funciona. Não sei porque, retirei o miolo com os dois for e o while funciona. Não encontro o erro.
package vetores;

import java.util.Scanner;

public class Media_2_vetores

{

public static void main(String[] args)

{

String[] nome_aluno = new String[50];

double[][] notas_aluno = new double[50][4];
int i,j;
	String opcao;
	String resp = "n";		
	double media = 0,soma = 0;
			
	Scanner sc = new Scanner(System.in);
	
	do
    {			
	
		for(i = 0;i < nome_aluno.length;i++)
		{
			System.out.println("Insira o nome do aluno: ");			
		    nome_aluno[i] = sc.next();	
		    
		     for(j = 0; j<4 ;j++)
		     {
		    	 System.out.println("Entre com a " + j + 1 + "  ª do aluno: ");
		    	 notas_aluno[i][j] = sc.nextDouble();
		    	 soma = soma + notas_aluno[i][j]; 	
		     }				     
		     	String aproveitamento = " ";
		     	switch(aproveitamento)
		     	{
	    	 		case "A":
	    	 		case "B":
	    	 		case "C": System.out.println("APROVADO"); break;
	    	 		case "D":
	    	 		case "E": System.out.println("REPROVADO"); break;  
		     	}	
	    	 
		     	System.out.println("Média: " + media);
		     	System.out.println("Conceito: " + aproveitamento);				
		     	System.out.println("Média: " + media);
		     	System.out.println("Conceito: " + aproveitamento);
		}
System.out.print("Deseja Continuar? <s/n>: ");
opcao = sc.next(); 
	} while (!opcao.equalsIgnoreCase(resp)); //while ( opcao != 'n'); // só pára se for == 'n'		
}

}

27 Respostas

staroski

Utilize somente o método nextLine() quando usar um Scanner para ler do TECLADO.

D

Obrigado. Só println de reprovado e aprovado que está fora do lugar. Já concertei.

D

Na verdade ainda tinha vários erros, concertei quase todos, mas há ainda erros.
Na segunda iteração dá erro é ignorado a entrada do nome do aluno, passa direto para inserir a nota, o código está dentro do loop, não sei porque não lê novamente e apresenta erro quando lê a nota se o vetor ainda não foi totalmente preenchido. Por algum motivo não está lendo o do-while. Não consigo descobrir.

D

<…
package vetores;

import java.util.Scanner;

public class Media_2_vetores

{

public static void main(String[] args)

{

String[] nome_aluno = new String[50];

double[] notas_aluno = new double[5];
int j;
	String opcao;
	//boolean opcao = true;
	String resp = "n";		
	double media = 0,soma = 0, cont =0;
			
	Scanner sc = new Scanner(System.in);
	
	do
    {			
	
		for(int i = 0;i < nome_aluno.length;i++)				
		{		
			System.out.println("Insira o nome do aluno: ");			
			nome_aluno[i] = sc.nextLine();
				for(j = 0; j<4 ;j++)
				{
						
					System.out.println("Entre com a " + (j + 1) + " ª nota do aluno: " + (i + 1));
					notas_aluno[j] = sc.nextDouble();
					soma = soma + notas_aluno[j]; 
					cont++;									    	 
				}		
		     
					media = soma / cont;
		     
					String aproveitamento = "";
					if (media >= 9 && media <= 10){
						aproveitamento = "A";
					} else if (media >= 7.5 && media < 9){
						aproveitamento = "B";
					} else if (media >= 6 && media < 7.5){
						aproveitamento = "C";
					} else if (media >= 4 && media < 6){
						aproveitamento = "D";
					} else if (media >= 0 && media < 4){
						aproveitamento = "E";
					} 
		        
					System.out.println("Média: " + media);
					System.out.println("Conceito: " + aproveitamento);				
	     	
					switch(aproveitamento)
					{
						case "A":
						case "B":
						case "C": System.out.println("APROVADO"); break;
						case "D":
	    	 		case "E": System.out.println("REPROVADO"); break;  
					}	
		
				//System.out.print("Deseja Continuar? <s/n>: ");					
				//opcao = sc.nextLine(); 
			
		}
	System.out.print("Deseja Continuar? <s/n>: ");
	//if (resp == false)
	opcao = sc.nextLine(); 
	} while (!opcao.equalsIgnoreCase(resp)); //while ( opcao != 'n'); // só pára se for == 'n'		
}

}…>

D

Estou passando passo a passo. Resolvi a parte dos nomes depois que coloquei nextLine() para limpar o buffer. Na segunda iteração não faz o cálculo correto. Soma, mas não divide e assim não apresenta a média correta. O código está correto, tem umas doideiras no java que eu não entendo.

D

Ainda não consegui resolver. Na segunda vez que faço para colocar as notas, as notas não são somadas corretamente. Parece que fica lixo na memória, não sei se está somando com o resultado da primeira iteração.
Por exemplo: 7 + 8 + 9 +8 dá 32, e fiz o debug e a soma está dando 142. Nada a ver. Resolvendo isso e resolvo depois a saída do algoritmo. Obrigado.

staroski

Você tem uma variável cont que só é incrementada.

Você não precisa dessa variável, utiliza o notas_aluno.length.

pmlm

Não estás a fazer reset da soma entre alunos. Cada aluno está a ficar com a soma do(s) anterior(es)

D
É verdade, retirei a variável cont. Ainda o while não funciona em qualquer lugar que eu coloque do código.

Interessante que  usei em outros código e funcionou.

<>

String opcao;

String resp = n;	

Scanner sc = new Scanner(System.in);
do
    {
	
	System.out.print("Deseja Continuar? <s/n>: ");
	opcao = sc.next();    	
	
	} while (!opcao.equalsIgnoreCase(resp)); <...>
pmlm

Já te disseram acima que deves:

staroski

Infelizmente muitos insistem no erro.
:pensive:

D

Obrigado pela dica.

D

Eu fiz como foi dito, mas ainda assim não funcionou. Vou pesquisar e encontrar a solução.

staroski

Deveria postar para vermos como você fez.

Assim funciona:

import java.io.PrintStream;
import java.util.Scanner;

public class Media_2_vetores {

    private static final Scanner in = new Scanner(System.in);
    private static final PrintStream out = System.out;

    public static void main(String[] args) {
        String[] nomes = new String[50];
        double[] notas = new double[4];

        String opcao;
        do {
            for (int i = 0; i < nomes.length; i++) {
                out.print("Insira o nome do aluno " + (i + 1) + ": ");
                nomes[i] = in.nextLine();

                double soma = 0;
                for (int j = 0; j < notas.length; j++) {
                    out.print("    Entre com a " + (j + 1) + "ª nota: ");
                    notas[j] = Double.parseDouble(in.nextLine());
                    soma += notas[j];
                }

                double media = soma / (double) notas.length;

                String conceito;
                if (media >= 9) {
                    conceito = "A";
                } else if (media >= 7.5) {
                    conceito = "B";
                } else if (media >= 6) {
                    conceito = "C";
                } else if (media >= 4) {
                    conceito = "D";
                } else {
                    conceito = "E";
                }

                String situacao;
                switch (conceito) {
                    case "A":
                    case "B":
                    case "C":
                        situacao = "APROVADO";
                        break;
                    default:
                        situacao = "REPROVADO";
                        break;
                }

                out.printf("    Média: %.2f%n", media);
                out.println("    Conceito: " + conceito);
                out.println("    " + situacao);
            }
            out.print("Deseja Continuar? <s/n>: ");
            opcao = in.nextLine();
        } while ("s".equalsIgnoreCase(opcao));
    }
}
D
Obrigado pelas respostas e ajuda de todos. Sim, coloco como fiz.

Consertei quase tudo. Vi onde estavam os erros. Agora creio ser problema de lógica mesmo.

package vetores;

import java.util.Scanner;
public class mediavetores2

{	

public static void main(String[] args)

{

String[] nome_aluno = new String[50];

double[] notas_aluno = new double[5];
int j;
	boolean opcao = true;
	String resp = " ";		 
	double media = 0,soma = 0;
			
	Scanner sc = new Scanner(System.in);		
	

do
{
	
		for(int i = 0;i < nome_aluno.length;i++)				
		{		
				System.out.println("Insira o nome do aluno: ");			 
				nome_aluno[i] = sc.next();
				soma = 0;
			
				while(opcao)
				{
					for(j = 0; j<4 ;j++)
					
					{						
						System.out.println("Entre com a " + (j + 1) + " ª nota do aluno: " + (i + 1)); 
						notas_aluno[j] = sc.nextDouble();
						soma = soma + notas_aluno[j]; 					
					} 
						
							media = soma / 5;
				     
							String aproveitamento = ""; 
							if (media >= 9 && media <= 10){
								aproveitamento = "A"; 
							} else if (media >= 7.5 && media < 9){
								aproveitamento = "B"; 
							} else if (media >= 6 && media < 7.5){
								aproveitamento = "C"; 
							} else if (media >= 4 && media < 6){
								aproveitamento = "D"; 
							} else if (media >= 0 && media < 4){
								aproveitamento = "E"; 
							} 
				        
							System.out.println("Média: " + media); 
							System.out.println("Conceito: " + aproveitamento);				 
			     	
							switch(aproveitamento)
							{
								case "A": 
								case "B": 
								case "C": System.out.println("APROVADO"); break;  
								case "D": 
								case "E": System.out.println("REPROVADO"); break;   
							}	
					
							System.out.print("Deseja Continuar? <s/n>: ");	 
							resp = sc.next();
							if(resp.equalsIgnoreCase("s")) 
								opcao = false;
				}
			}
		}while(opcao);
			System.out.print("Deseja Continuar? <s/n>: ");	 
			resp = sc.next();
			if(resp.equalsIgnoreCase("s")) 
				opcao = false;
		
	sc.next();
	sc.close();
}

}
Testei as duas maneiras para saber como funciona o while. No primeiro ele faz a pergunta se deseja sair do loop, porém volta para pedir novamente o aluno 1, está errado, é para sair deste loop e ir para o loop mais externo e fazer a pergunta.
O mais interno é para contar as 4 notas de cada aluno. O mais externo é para sair da contagem dos 50 alunos.
Bem, aprendizado é isso mesmo, vou ver com calma e posto aqui. Obrigado a todos.

staroski

Quando postar código no fórum, formata ele certinho:
formatacao-forum

Seu fonte continua utilizando os métodos next e nextDouble, você já foi orientado a utilizar somente o nextLine().
O seu Scanner encapsula o System.in, que corresponde ao TECLADO e o ÚNICO método do Scanner que consome adequadamente a quebra de linha ao pressionar ENTER é o método nextLine().
Todos os outros métodos do Scanner processam TOKENS e não LINHAS. :wink:

Você continua tendo um array de 5 notas mas só lê 4.

Acho que é falta de atenção (ou teimosia :stuck_out_tongue: ).

Coloquei alguns comentários no seu fonte:

public class mediavetores2 {

    public static void main(String[] args) {
        String[] nome_aluno = new String[50];
        double[] notas_aluno = new double[5];

        int j; // pra que declarar o j aqui em cima se ele só faz parte do for que tem lá embaixo?
        boolean opcao = true; // tem que inicializar com true dentro do laço 'do-while'
        String resp = " ";
        double media = 0, soma = 0; // essas duas variáveis aqui podem ser declaradas dentro do while

        Scanner sc = new Scanner(System.in);

        do {

            for (int i = 0; i < nome_aluno.length; i++) {
                System.out.println("Insira o nome do aluno: ");
                nome_aluno[i] = sc.next(); // usa sc.nextLine()
                soma = 0;

                while (opcao) { // pra que esse while aqui? você já tem o `do-while`
                    for (j = 0; j < 4; j++) // porque 4 ? usa o notas_aluno.length

                    {
                        System.out.println("Entre com a " + (j + 1) + " ª nota do aluno: " + (i + 1));
                        notas_aluno[j] = sc.nextDouble(); // usa Double.parseDouble(sc.nextLine())
                        soma = soma + notas_aluno[j];
                    }

                    media = soma / 5; // pq 5 ? usa o notas_aluno.length

                    String aproveitamento = "";
                    if (media >= 9 && media <= 10) {
                        aproveitamento = "A";
                    } else if (media >= 7.5 && media < 9) { // não precisa testar se é < 9
                        aproveitamento = "B";
                    } else if (media >= 6 && media < 7.5) { // não precisa testar se é < 7.5
                        aproveitamento = "C";
                    } else if (media >= 4 && media < 6) { // não precisa testar se é < 6
                        aproveitamento = "D";
                    } else if (media >= 0 && media < 4) { // não precisa testar se é < 4
                        aproveitamento = "E";
                    }

                    System.out.println("Média: " + media);
                    System.out.println("Conceito: " + aproveitamento);

                    switch (aproveitamento) {
                        case "A":
                        case "B":
                        case "C":
                            System.out.println("APROVADO");
                            break;
                        case "D":
                        case "E":
                            System.out.println("REPROVADO");
                            break;
                    }

                    System.out.print("Deseja Continuar? <s/n>: ");
                    resp = sc.next(); // usa sc.nextLine()
                    if (resp.equalsIgnoreCase("s"))
                        opcao = false;
                }
            }
        } while (opcao);

        // o código que tem daqui pra baixo é desnecessário
        System.out.print("Deseja Continuar? <s/n>: ");
        resp = sc.next();
        if (resp.equalsIgnoreCase("s"))
            opcao = false;

        sc.next();
        sc.close(); // não se deve fechar o System.in, seu Scanner encapsula o System.in
    }
}
D

Esqueci do quote de novo. Desculpe.

D

Falta de atenção. Estou aprendendo e posso perder algo. Teimosia não.

D

Ok. O primeiro while é para sair dos 50 vezes, as vezes não temos 50 alunos, o mesmo vale para as quatro notas do aluno, pode ser da não existência das 4 notas, somente três, assim poder sair do loop. Pensei aqui, posso ver um modo de se não existir algum item, o compilador ir automáticamente para o próximo. Tanto faz usar 5 ou o tamanho do vetor. Fiz as correções. Fiz isso para complicar um pouco e aprender.

D

Não tinha entendido das outras vezes o que você quiz dizer, assim não fiz as modificações necessárias. Tudo bem.

D

Só peço um pouco de calma para quem está aprendendo, ok?

D

Para que a conversão de Double para nextLine?

G

Amigo recomendo você ler mais um pouco, ver videos e começar a entender pelo menos o básico da lógica de programação, assim fica mais fácil te ajudar e você aprender. O amigo ali postou um código todo comentado sobre.

E sobre sua ultima pergunta, acredito, pelo contexto que seja para transformar o que o usuário escreveu (String) em um número (Double) para depois manipular mais facilmente esse valor como um número de fato ao invés de texto.

D

Ok. Obrigado pela dica. Sim, eu vi o código, antes disso eu não estava entendendo o que ele queria passar. Vou estudar mais. Na verdade é o que eu estou fazendo.

D

GabrielA2: ainda não estudei sobre métodos de conversões. Entendo o funcionamento de um algoritmo, lógica estudei bastante, o problema é a sintaxe da linguagem ainda a aprender, tento resolver e quando não descubro a solução peço ajuda para aprender e ver onde estou errando.

staroski

Mas ninguém está perdendo a calma.
Mesmo você ignorando a ajuda e não fazendo o que estamos orientando, estamos tentando ajudar.

Então porque não faz as alterações que sugerimos?
Você simplesmente ignora e depois de alguns dias posta o mesmo problema.
🤷

D

Erro meu, ok. Vamos em frente.

Criado 22 de janeiro de 2021
Ultima resposta 3 de fev. de 2021
Respostas 27
Participantes 4