While infinito java

18 respostas
whilejava
W

Bom dia, estou fazendo um programa para a faculdade e basicamente esta completo, porem em um dos métodos, meu while fica em loop infinito. Segue o código abaixo:

package br.edu.principal;

import java.util.Scanner;

public class Notas{
	
	Scanner ler = new Scanner (System.in);

	float notas[][] = new float[6][2];

	String materias[] = new String [6];

	int contador = 0;
	
	String[] lerMaterias(){

		while (contador <= 5){

			System.out.println("");
			System.out.printf ("Insira o nome da materia %d: ",(contador+1));
			materias[contador] = ler.nextLine();
			System.out.println("");

			lerNotas();

			contador ++;
		}

		return materias;
	}

	float[][] lerNotas(){

			System.out.println("");
			System.out.printf ("Insira a primeira nota da materia %s: ", materias[contador]);
			notas[contador][0] = Float.parseFloat(ler.nextLine());
			System.out.println("");

			System.out.println("");
			System.out.printf ("Insira a segunda nota da materia %s: ", materias[contador]);
			notas[contador][1] = Float.parseFloat(ler.nextLine());
			System.out.println("");	

		return notas;

		}
}

após a 6ª matéria ele começa a pedir a matéria “null”.

18 Respostas

staroski

Como é que você está executando essa classe Notas, como é seu método main?

Executei da seguinte forma e funcionou perfeitamente:

Notas notas= new Notas();
notas.lerMaterias();
W

Meu método main está assim:

public static void main(String[] args){

		Notas classeNotas = new Notas();
		Medias classeMedias = new Medias();

		String[] materias = classeNotas.lerMaterias();
		float[] medias = classeMedias.calculaMedia();

		classeNotas.lerMaterias();
		classeNotas.lerNotas();
		classeMedias.calculaMedia();
}
staroski

No código que você postou antes, o método lerNotas é chamado de dentro do método lerMaterias
E agora no main você chama ele de novo.

W

Já retirei essa segunda vez que chamo ele, porem ainda assim ele aparece mais uma vez

staroski

Então posta o código atualizado dos seus fontes, senão fica difícil te indicar a causa do erro.

L

vocé esta atribuindo os atributos sem usar metodo. Nunca fiz isso assim em java, não vou mentir, mas seria mais viável se tentasse usar metodos no lugar de classificar os atributos diretamente, pois é linguagem Orient. a objetos: no lugar de String[] lerMaterias() e lerNotas, use public String lerMateriais e public float LerNotas
com retorno e tudo mais dentro , e na hora de calcular médias, passe as notas como parâmetro

L

Se voce já tiver um numero definido de repetições, use o for. E está incoerente voce chamar o lerNotas dentro de ler Materias, talvez por isso deu erro. Tire de dentro, métodos em Java devem ser , por padrao, os mais objetivos possíveis, não que seja errado colocar um metodo dentro de outro, mas pra tipos primitivos como string e float nao da muito certo. Faca tudo na função Main mesmo

W

eu chamo o lerNotas() dentro do lerMaterias() para que logo após colocar o nome da matéria já peça as notas da mesma

W

Classe Notas:

package br.edu.principal;

import java.util.Scanner;

public class Notas{
	
	Scanner ler = new Scanner (System.in);

	float notas[][] = new float[6][2];

	String materias[] = new String [6];

	int contador = 0;
	
	String[] lerMaterias(){

		while (contador <= 5){

			System.out.println("");
			System.out.printf ("Insira o nome da materia %d: ",(contador+1));
			materias[contador] = ler.nextLine();
			System.out.println("");

			lerNotas();

			contador ++;
		}

		return materias;
	}

	float[][] lerNotas(){

			System.out.println("");
			System.out.printf ("Insira a primeira nota da materia %s: ", materias[contador]);
			notas[contador][0] = Float.parseFloat(ler.nextLine());
			System.out.println("");

			System.out.println("");
			System.out.printf ("Insira a segunda nota da materia %s: ", materias[contador]);
			notas[contador][1] = Float.parseFloat(ler.nextLine());
			System.out.println("");	

		return notas;

		}
}

Classe Medias:

package br.edu.principal;

public class Medias{

	Notas classeNotas = new Notas();

	float media[] = new float[6];

	float[] calculaMedia(){

		int contador = 0;

		float[][] notas = classeNotas.lerNotas();

		while (contador <= 5){

			media[contador] = (notas[contador][1] + notas[contador][2])/2;

			contador ++;
		}

		return media;
	}
}

Classe Validacao:

package br.edu.principal;

public class Validacao{

	public static void main(String[] args){

		Notas classeNotas = new Notas();
		Medias classeMedias = new Medias();

		String[] materias = classeNotas.lerMaterias();
		float[] medias = classeMedias.calculaMedia();

		int contador = 0;

		classeNotas.lerMaterias();
		classeMedias.calculaMedia();

		while (contador <=5){

			if (medias[contador] >= 70){

				System.out.printf("Sua media na matéria %s foi %.2f e voce foi aprovado!",materias[contador],medias[contador]);			
			}

			if (medias[contador] < 70 & medias[contador] > 30){

				System.out.printf("Sua media na matéria %s foi %.2f e voce ficou em exame!",materias[contador],medias[contador]);			
			}

			if (medias[contador] < 30){

				System.out.printf("Sua media na matéria %s foi %.2f e voce reprovou!",materias[contador],medias[contador]);			
			}
		}
	}
}
L

classeMedias.calculaMedia() tem de receber algum parametro, pra calcular a media

L

Ah, e em lerNotas, como não tem while dentro, não pode chama-lo dentro da posição de laço de repetição. O seu raciocínio até que é bom, mas a lógica precisa ser aperfeiçoada, continue praticando. Se você está agora em Linguagem O.Objetos, pratique tbm os seus termos: objetos, get, set, etc.

staroski

É que no método calculaMedia da classe Medias você está criando um novo objeto do tipo Notas e novamente chamando o método lerNotas

W

Foi o que fiz para o método calculaMedia() receber as notas para fazer o calculo, teria outro modo?
Pois preciso pegar o retorno de lerNotas(), fiz isso no main com o lerMaterias() e ainda assim não chamou o método mais uma vez

W

Ele recebe o retorno de lerNotas() dentro da classe dele

W

O professor especificou que logo após pedir o nome da matéria ja deveria pedir as notas, foi o modo que encontrei, pois como o método é String, não poderia retornar as duas variáveis se colocasse os dois no mesmo método

L

Nao, voce só esta criando uma nova instancia de classes média, fora o que voce já esta chamando, logo são duas leituras.

L

Entendi o que quis fazer, só que está criando um novo objeto em vez de pegar o anterior:logo depois de voce pegar a notas, voce pode calcular logo as medias, pegando notas como parâmetro:

calcularMedias (notas) , incluindo dentro de ler materias, depois de ler notas, que recebe o resultado de ler notas, antes de acrescentar o contador

staroski

Para um método receber algo como parâmetro, você precisa passar parâmetros para ele, mas em momento algum você faz isso.

Eu faria algo assim, primeiro criaria uma classe Materia contendo o nome, as notas e um método pra calcular a media:

public class Materia {

    private String nome;
    private float[] notas;

    public Materia(String nome, float... notas) {
        this.nome = nome;
        this.notas = notas;
    }

    public String getNome() {
        return nome;
    }

    public float[] getNotas() {
        return notas;
    }

    public float calcularMedia() {
        float soma = 0;
        for (float nota : notas) {
            soma += nota;
        }
        float quantidade = notas.length;
        return soma / quantidade;
    }
}

Em seguida escreveria o programa para ler as entradas e imprimir as saídas:

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

public class Programa {

    public static void main(String[] args) {
        try {
            Programa programa = new Programa();
            programa.executar();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

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

    private void executar() {
        Materia[] materias = lerMaterias(5);
        for (Materia materia : materias) {
            float media = materia.calcularMedia();
            String nome = materia.getNome();
            if (media >= 7) {
                saida.printf("Sua media na matéria %s foi %.2f e voce foi aprovado!%n", nome, media);
            } else if (media >= 3) {
                saida.printf("Sua media na matéria %s foi %.2f e voce ficou em exame!%n", nome, media);
            } else {
                saida.printf("Sua media na matéria %s foi %.2f e voce reprovou!%n", nome, media);
            }
        }
    }

    private Materia[] lerMaterias(int quantidade) {
        Materia[] materias = new Materia[quantidade];
        for (int i = 0; i < quantidade; i++) {
            saida.printf("Insira o nome da materia %d: ", (i + 1));
            String nome = entrada.nextLine();
            float[] notas = lerNotas(nome, 2);
            materias[i] = new Materia(nome, notas);
        }
        saida.println();
        return materias;
    }

    private float[] lerNotas(String nome, int quantidade) {
        saida.printf("Insira a primeira nota da materia %s: ", nome);
        float nota1 = Float.parseFloat(entrada.nextLine());
        saida.printf("Insira a segunda nota da materia %s: ", nome);
        float nota2 = Float.parseFloat(entrada.nextLine());
        saida.println();
        return new float[] { nota1, nota2 };
    }
}
Criado 19 de agosto de 2019
Ultima resposta 19 de ago. de 2019
Respostas 18
Participantes 3