Dá Certo Quando É com 1 ou 2 Termos e Dá Errado Quando É com Mais
14 respostasResolvido
java
Advanced-S17
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?
packagecurso.basico.java.com.loiane.cursojava.aula17.labs;importjava.util.Scanner;publicclassExerc21Ver2{publicstaticvoidmain(String[]args){Scannerscan=newScanner(System.in);Stringop="+";intsoma=0;intalunos=0;inttrocaAlunos=0;intcont=0;intmedia=0;while(op.equals("+")){cont++;// 1 // 2 // 3System.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=40trocaAlunos=alunos;// 10 // 20 // 30 // media=soma/cont;// 10/1=10 // 20/2=10 // 30/3=10if(op.equals("=")){soma=alunos+trocaAlunos;// 10+0=10 // 10+10=20 // 10+20=30 // 10+30=40trocaAlunos=alunos;// 10 // 20 // 30 // media=soma/cont;// 10/1=10 // 20/2=10 // 30/3=10System.out.println(soma);System.out.println(cont);System.out.println("A média de alunos por sala é : "+media);// 10}}}}
Me desculpe, se não entendi. Mas como me explica o fato de nextInt e next ler as linhas ao usar 1 ou 2 termos?
darlan_machado
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:
Stringnome=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)intidade=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)Stringemail=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.
Ficou mais claro?
Advanced-S17
Certo, porém mesmo mudando os next da parte das Strings, dá a média errada, sem somar o terceiro termo.
darlan_machado
Uma coisa é você ajustar as entradas, outra é você corrigir a lógica.
Advanced-S17
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.
darlan_machado
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?
Advanced-S17
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.
darlan_machado
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"Varsoma,alunos,cont:inteiromedia:realop:caractereIniciosoma<-0alunos<-0cont<-0media<-0op<-"+"enquantoop="+"facaescreval("Informe a quantidade de alunos da turma")leia(alunos)soma<-soma+alunoscont<-cont+1escreval("Digite '+' para adicionar mais turmas ou '=' para exibir a média")leia(op)fimenquantomedia<-soma/contescreval("A média de alunos por turma é: ",media)Fimalgoritmo
Advanced-S17
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.
darlan_machado
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;
importjava.util.Scanner;publicclassExerc21Ver2{publicstaticvoidmain(String[]args){Scannerscan=newScanner(System.in);Stringop="+";intsoma=0;intalunos=0;inttrocaAlunos=0;intcont=0;intmedia=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 somasoma=alunos+trocaAlunos;//Novamente o trecho que não deve ficar no looptrocaAlunos=alunos;media=soma/cont;System.out.println(soma);System.out.println(cont);System.out.println("A média de alunos por sala é : "+media);}}}
}
Solucao aceita
darlan_machado
Eu não sei se você já estudou isso, mas, esta sintaxe é desnecessária.
Você pode, simplesmente, fazer isso:
soma+=alunos;//Que é o equivalente asoma=soma+alunos;
Uma vez que você atribuiu, corretamente, o valor 0 à variável soma, antes do loop, esta sintaxe acima vai funcionar perfeitamente.
Advanced-S17
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.
darlan_machado
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.”.