Saída while encerrar programa não funciona

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'		
}

}

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

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

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.

<…
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'		
}

}…>

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.

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.

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

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

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

É verdade, retirei a variável cont. Ainda o while não funciona em qualquer lugar que eu coloque do código.
Interessante que já 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)); <...>

Já te disseram acima que deves:

1 curtida

Infelizmente muitos insistem no erro.
:pensive:

1 curtida

Obrigado pela dica.

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

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));
    }
}

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.

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
    }
}

Esqueci do quote de novo. Desculpe.

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

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.