Problema com loop

Fala ae pessoal, eu estava tentando fazer um programa em java para treinar um pouco, mas o programa esta com um erro que eu não consegui resolver. Independente de qual valor eu digite, ele sempre imprime 2x Digite o nome do Mercado e depois roda normal.
Exemplo: Digito 4, ele imprime:
Digite o nome do Mercado
Digite o nome do Mercado

e depois roda normal, recebendo os valores do teclado.

eu olhei o loop varia vezes, mas não consigo ver o erro.

Obs: Eu estou começando a ler Use a cabeça! Java, mas ainda estou no capitulo 2.

[code]import java.util.Scanner;
public class ex {
static Scanner entrada = new Scanner (System.in);
static String[] mercado= new String [100];
static int i;

public static void main (String[] args){
	
	System.out.print("Quantos mercados deseja inserir ?");
		int n = entrada.nextInt();
	
	armazenaMercado(n);
	
	
	
	

}

public static void armazenaMercado(int n){
	
	for(i=0; i <n; i++){
		System.out.println("Digite o nome do Mercado ");
		mercado[i] = entrada.nextLine();
		
	}
	imprimeMercado(n);
}

public static void imprimeMercado(int n){
	
	for(i=0; i<n; i++){
		System.out.println(mercado[i]);
	}
	
}

}[/code]

É só vc trocar o

mercado[i] = entrada.nextLine(); 

por

mercado[i] = entrada.next(); 

que funfa legal! :lol:

Testei aqui e funciono perfeitamente, obrigado.

Mas fiquei com uma duvida. Você sabe me dizer porque não funcionou com nextLine?

Na realidade, o nextLine está bem e deves deixar ficar com nextLine.

O problema está no nextInt que tu tens anteriormente. O único método da classe Scanner que se deve utilizar quando se lêm dados do teclado é o nextLine. Usando outros (como o nextInt ou o next) podes ter esse problema.

No teu caso aoo fazer nextInt, tu introduzes, por exemplo, 5 e carregas em enter. O nextInt só vai ler o 5. O enter fica à espera de ser lido. Ao chegar ao primeiro nextLine, como já lá tem um enter, vai ler esse enter, passando para o nextLine seguinte onde fica à espera que tu introduzas os teus dados.

Então o nexInt() deveria ser usado só se eu no lugar de dar enter clica-se em um botão, ou algo do tipo?
Se eu for capturar do teclado eu devo usar o nextLine() e depois converter para inteiro?

o caso de converter ficaria assim, correto?

[code]import java.util.Scanner;
public class ex {
static Scanner entrada = new Scanner (System.in);
static String[] mercado= new String [100];
static int i;

    public static void main (String[] args){  
          
        System.out.print("Quantos mercados deseja inserir ?");  
            String n2 = entrada.nextLine();
            int n = Integer.parseInt(n2);
          
        armazenaMercado(n);  
          
          
          
          
  
    }  
      
    public static void armazenaMercado(int n){  
          
        for(i=0; i <n; i++){  
            System.out.println("Digite o nome do Mercado ");  
            mercado[i] = entrada.nextLine();  
              
        }  
        imprimeMercado(n);  
    }  
      
    public static void imprimeMercado(int n){  
          
        for(i=0; i<n; i++){  
            System.out.println(mercado[i]);  
        }  
          
    }  
  
}  

[/code]

No lugar de

String n2 = entrada.nextLine();
int n = Integer.parseInt(n2);

Você poderia simplificar com:

int n = Integer.parseInt(entrada.nextLine());

Para não precisar usar duas variáveis.

[quote=cogumello]No lugar de

String n2 = entrada.nextLine();
int n = Integer.parseInt(n2);

Você poderia simplificar com:

int n = Integer.parseInt(entrada.nextLine());

Para não precisar usar duas variáveis.

[/quote]

Esse é o conselho que costuma ser mais prejudicial que benéfico. Usar variáveis locais não gasta mais CPU nem espaço em memória, e ajuda a deixar seu programa mais claro.
Adicionalmente, permite descobrir oportunidades de reusar resultados e evitar processamento desnecessário.
Não fique economizando variáveis locais, é uma economia besta.

O conselho correto a ser dado é: evite usar static (exceto pelo “public static void main” - é uma coisa inevitável :slight_smile: ) - você vai me agradecer mais tarde.

Vou reescrever seu programa para evitar o uso desnecessário de static.
Em comentários eu estou indicando também algumas coisas interessantes que você deve se acostumar a fazer.

import java.util.Scanner;    
// Acostume-se a declarar classes com a primeira letra em maiúscula!
public class Ex {    

	// Evite usar variáveis static, a menos que elas sejam "public final static " (ou seja, constantes)
	// Evite ter métodos estáticos, exceto o main e rotinas utilitárias, que não dependem da classe
	public static void main (String[] args){    
		// Sempre crie um objeto, mesmo que seja só para chamar um único método dele
		// (como estou fazendo abaixo).
		Ex exemplo = new Ex();
		
		System.out.print("Quantos mercados deseja inserir ?");    
		String n2 = entrada.nextLine();  
		int n = Integer.parseInt(n2);  
		ex.armazenaMercado(n);
	}    
	
	public void armazenaMercado (int n){    
		// Sempre declare os contadores dentro do for, não fora dele
		for (int i = 0; i < n; i++) {    
			System.out.println("Digite o nome do Mercado ");    
			mercado[i] = entrada.nextLine();    
		}    
		imprimeMercado(n);    
	}    
	
	public void imprimeMercado (int n) {    
		for(int i = 0; i < n; i++) {    
			System.out.println(mercado[i]);    
		}    
	}
	
	// Evite deixar uma variável sem declaração de "private" a menos que você vá usá-la em outra classe 
	private Scanner entrada = new Scanner (System.in);    
	private String[] mercado = new String [100];    
}    

Obrigado ae pessoal, vocês me ajudaram bastante.

entanglement
Entendi, essa informação foi muito boa, eu realmente estava achando que economizar variáveis ajudaria na execução do programa.
Obrigado.

@edit

Vou sair agora, mas assim que voltar estudo as mudanças que você fez o código, elas vão me ajudar bastante na minha caminhada =)

[quote=Starkk]Então o nexInt() deveria ser usado só se eu no lugar de dar enter clica-se em um botão, ou algo do tipo?
[/quote]
Devem ser usados se estiveres a ler de um ficheiro.

[quote=pmlm][quote=Starkk]Então o nexInt() deveria ser usado só se eu no lugar de dar enter clica-se em um botão, ou algo do tipo?
[/quote]
Devem ser usados se estiveres a ler de um ficheiro.[/quote]

Entendi, obrigadão pela ajuda.

entanglement
Não aguentei, tive que olhar o código antes de sair, rs.

O código não rodou, então tive que alterar 2 coisas.

ex.armazenaMercado(n);[/code] para [code]exemplo.armazenaMercado(n);

e

private Scanner entrada = new Scanner (System.in);  [/code] para [code]private static Scanner entrada = new Scanner (System.in);  

ai ele rodou.

Fiquei com 2 duvidas:
1° - Porque o Scanner foi declarado no final?
2° - Porque devo sempre criar um objeto, mesmo que seja só para chamar um único método dele?

O código me ajudou bastante, eu não sabia que podia declarar o contador dentro do laço, nem que podia(e devia) ter métodos(com exceção do main) sem ser estáticos.

Obs: Qualquer dica é sempre muito bem-vinda =)

  1. Realmente náo testei o programa - desculpe
  2. Eu fiz isso para tirar tudo que é static desnecessário, além disso (não exatamente nesse caso) você poderia ter N objetos dessa classe,
  3. Em Java é melhor você declarar tudo que é mais importante primeiro, e deixar os detalhes para o final. Fazer isso (deixar as coisas “public” primeiro e as “private” depois) faz com que alguém, que vá olhar seu código, veja primeiro o que é mais importante, e depois vá para os detalhes se for necessário.

Em outras linguagens (como em C, C++ ou Pascal) é necessário declarar primeiro tudo que vai ser usado depois, mesmo que seja só um detalhe de implementação irrelevante.
Em Pascal há a palavra-chave “forward” e em C++ há “declarações incompletas” para poder declarar algo que na verdade você só gostaria de (ou poderia) declarar depois, mas são coisas um pouco difíceis de usar.
Isso faz com que você acabe tendo de ficar tendo o costume de ficar procurando as coisas importantes pelo código todo, em vez de simplesmente ler só o começo (onde deveriam estar as coisas importantes), como em um programa em Java bem-estruturado.

Esqueci que o “entrada” estava sendo usado pelo “main” e pela classe Ex (argh). Mas a história do static indica que ainda há um probleminha nessa classe. Vou tomar vergonha e corrigir a classe do jeito certo.

Entendi, obrigadão pela ajuda =)