Vou apresentar o código abaixo com algumas repetições desnecessárias só pra mostrar que mesmo repetindo operações de soma, depois de executado, o programa apresenta o resultado como se não tivesse somado o terceiro termo. O que pode ser?
package curso.basico.java.com.loiane.cursojava.aula17.labs;
import java.util.Scanner;
public class Exerc21Ver2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String op = "+";
int soma = 0;
int alunos = 0;
int trocaAlunos = 0;
int cont = 0;
int media = 0;
while(op.equals("+")) {
cont++; // 1 // 2 // 3
System.out.println(cont);
System.out.println("Entre com a quantidade de alunos por turma e separe-as" + " por enter ou espaço.");
alunos = scan.nextInt();// 10 // 10 // 10
/* VALIDAÇÃO */
if(alunos>40 | alunos <1) {
System.out.println("Uma turma não pode ter mais de 40 " + "alunos ou menos de 1." + " Entre com um valor válido.");
alunos = scan.nextInt();
}
/* FIM DA VALIDAÇÃO */
System.out.println("Digite \" + \" para continuar somando ou \" = \" para" + " exibir a média por turma.");
op = scan.next(); // + // + // =
/* VALIDAÇÃO */
if( ! op.equals("=") & ! op.equals("+")){
do {
System.out.println("Operação inválida. Digite um dos dois" + " operadores citados anteriormente.");
op = scan.next();
} while(!op.equals("=") & !op.equals("+"));
}
/* FIM DA VALIDAÇÃO */
soma = alunos+trocaAlunos; // 10+0=10 // 10+10=20 // 10+20=30 // 10+30=40
trocaAlunos = alunos; // 10 // 20 // 30 //
media = soma / cont; // 10/1=10 // 20/2=10 // 30/3=10
if(op.equals("=")) {
soma = alunos+trocaAlunos; // 10+0=10 // 10+10=20 // 10+20=30 // 10+30=40
trocaAlunos = alunos; // 10 // 20 // 30 //
media = soma / cont; // 10/1=10 // 20/2=10 // 30/3=10
System.out.println(soma);
System.out.println(cont);
System.out.println("A média de alunos por sala é : " + media); // 10
}
}
}
}
O que acontece é que o comportamento dos métodos de leitura da classe Scanner são bem definidos e, mesmo que pareça idiota, seguem uma lógica coerente.
Veja, o exemplo abaixo:
String nome = sc.nextLine();//Aqui li a próxima linha, desde o primeiro caractere até o \n q indica que a linha terminou (o \n é o representante do enter pressionado pelo usuário indicando que ele digitou o valor solicitado)
int idade = sc.nextInt();//Aqui eu leio apenas a parte inteira, não me interessa nada além da parte inteira (isso significa que o \n que indica que o usuário pressionou enter informando ter inserido o valor solicitado foi ignorado)
String email = sc.nextLine();//Aqui leio a primeira linha, que, coincidentemente, é composta pelo \n que o usuário já havia inserido.
Explicando com mais detalhes: o método nextLine lê a próxima linha disponível. O método identifica uma linha como sendo qualquer coisa digitada e que tenha sido encerrada com o \n.
Já os métodos nextInt, nextFloat, nextBoolean, next… só podem ler as partes que lhes cabem. Assim sendo, ignoram o restante da linha e não dão um jeito no \n que o usuário insere quando pressiona enter e diz a entrada padrão do sistema (System.in) que está terminada a instrução.
Desta maneira, o correto é usar os wrappers. É uma pegadinha comum pedir para criar coisas como o exemplo que coloquei. Em minhas aulas eu sempre fazia isso. Era uma maneira de estimular o próximo passo.
Tudo bem, Darlan, porém ao observar suas primeiras respostas, qualquer um será levado a acreditar que o problema se deveu ao fato de não ter sido possível entrar os valores nas variáveis, por causa dos next e nextInt.
Foi por tentar encontrar o erro da lógica e não ter encontrado em mais de 30 minutos que não consigo achar um erro de lógica, parece ser um erro da JDK ou algo da IDE.
Veja bem, até citei a tua pergunta para justificar o que coloquei.
Quando você está desenvolvendo, corre o risco de criar algo com N bugs. Alguns podem obscurecer ou esconder outros.
Outro detalhe, você colocou o código e não informou o que realmente deseja fazer. Eu não faço o curso da loiane e, assim sendo, não sei quais são as coisas que você precisa obter como resultados com este exercício.
De qualquer maneira, é bastante difícil ser um erro do JDK.
A IDE eu não tenho como saber, afinal, você também não disse qual está usando, mas, mesmo que seja um BlueJ da vida (se é que ainda existe), também penso que seja bem difícil ser este o problema.
Portanto, para que possamos ser mais assertivos, poderia, por gentileza, postar qual o enunciado do exercício?
O exercício pede para criar um programa que peça ao usuário digitar quantidades de alunos por turma, mas sem pedir a quantidade de turmas, já pra forçar o uso do laço de repetição, independente da quantidade de turmas que uma escola pode ter, por isso o uso do laço.
No final, exibir a média de alunos por turma.
A lógica é bem simples, onde vai somando a quantidade de alunos por turma e depois divide a quantidade total pelo número de turmas.
Eu passei e repassei o código e não encontrei um erro de lógica que possa tornar o resultado errado.
Cara, a questão funciona assim.
Eu revisei teu código e vi que, realmente, está com problemas na execução.
Troquei as entradas de nextInt e next para nextLine e fiz a conversão dos valores.
Agora, para quê serve a variável trocaAluno?
Eu montei um algoritmo que está rodando.
Algoritmo "media"
Var
soma, alunos, cont : inteiro
media : real
op : caractere
Inicio
soma <- 0
alunos <-0
cont <- 0
media <- 0
op <- "+"
enquanto op = "+" faca
escreval("Informe a quantidade de alunos da turma")
leia(alunos)
soma <- soma + alunos
cont <- cont + 1
escreval("Digite '+' para adicionar mais turmas ou '=' para exibir a média")
leia(op)
fimenquanto
media <- soma / cont
escreval("A média de alunos por turma é: ", media)
Fimalgoritmo
Agradeço a presteza em responder.
A variável trocaAlunos serve para pegar o valor atual e ir aumentando com o valor total de alunos, vai aumentando com a soma dos alunos e a variável alunos pega a última quantidade de alunos digitada pelo usuário.
Quando chega na atribuição de valor da variável soma, ela recebe a última quantidade de alunos da última turma da variável alunos e soma ao valor total anterior de alunos dentro da variável trocaAlunos.
Dá uma olhada nos comentário que coloquei e daí me diz se não tem nada errado na implementação…
package curso.basico.java.com.loiane.cursojava.aula17.labs;
import java.util.Scanner;
public class Exerc21Ver2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String op = "+";
int soma = 0;
int alunos = 0;
int trocaAlunos = 0;
int cont = 0;
int media = 0;
while(op.equals("+")) {
cont++;
System.out.println(cont);
System.out.println("Entre com a quantidade de alunos por turma e separe-as" + " por enter ou espaço.");
alunos = scan.nextInt();
/* VALIDAÇÃO */
if(alunos>40 | alunos <1) {
System.out.println("Uma turma não pode ter mais de 40 " + "alunos ou menos de 1." + " Entre com um valor válido.");
alunos = scan.nextInt();
}
/* FIM DA VALIDAÇÃO */
System.out.println("Digite \" + \" para continuar somando ou \" = \" para" + " exibir a média por turma.");
op = scan.next();
/* VALIDAÇÃO */
if( ! op.equals("=") & ! op.equals("+")){
do {
System.out.println("Operação inválida. Digite um dos dois" + " operadores citados anteriormente.");
op = scan.next();
} while(!op.equals("=") & !op.equals("+"));
}
/* FIM DA VALIDAÇÃO */
/*
Cada nova iteração, a soma recebe um valor diferente e igual ao último valor digitado para "alunos"
O certo deveria ser
soma <- soma + (alunos + trocaAlunos)
*/
soma = alunos+trocaAlunos;
/*
Este trecho jamais pode ficar dentro do loop!
*/
trocaAlunos = alunos;
media = soma / cont;
if(op.equals("=")) {
//Novamente a atribução incorreta da soma
soma = alunos+trocaAlunos;
//Novamente o trecho que não deve ficar no loop
trocaAlunos = alunos;
media = soma / cont;
System.out.println(soma);
System.out.println(cont);
System.out.println("A média de alunos por sala é : " + media);
}
}
}
Finalmente, funcionou.
Agora, o que não entendo é que apesar do seu código ser mais simples e ter funcionado, não consegui encontrar o erro de lógica do primeiro código.
De qualquer forma, não farei mais daquele jeito.
Deixa eu listar aqui o que você fez de errado.
1 - Sempre, toda vez que precisar realizar cálculos como média, você precisa fazer isso depois de ter colhido todas as informações relevantes (basicamente a soma de todos os elementos que entrarão no cálculo e a quantidade de elementos pelos quais haverá a divisão). Ou seja, nunca colocar o cálculo no laço de repetição (for/while/do-while).
2 - Além do erro acima, você tinha uma duplicidade no cálculo do valor da média, pois, tinha um trecho anterior ao que comparava a operação como sendo “=”. Isso interferia no resultado.
3 - Não que fosse o problema, mas você tinha uma variável soma e a usava de forma não convencional (veja, não é que estivesse errado, mas, normalmente, o uso e “soma += valor.”.