LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 12-01-2007, 10:18 AM   #1
Cyhaxor
Member
 
Registered: Nov 2004
Location: UK
Distribution: Fedora 12
Posts: 129

Rep: Reputation: 15
Question Strange java algorithm!


Code:
import java.util.Scanner;
class test {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = 0;
		int i=0;
		System.out.println("How many names?");
		n = sc.nextInt();
		String[] arrayString = new String[n];
		arrayString[i] = sc.nextLine(); // notice this request for input before the loop (seems to be useless)
		for (i=0; i<n; i++) {
			System.out.println("Give the name:");
			arrayString[i] = sc.nextLine(); // request for input inside the loop.
		}
		
		for (i=0; i<arrayString.length; i++) {
			System.out.println(arrayString[i]);
		}
	}
}
Ok the above code is working fine and it got me 30mins to find the right algorithm.

The strange thing is that: Let's rewrite the above code slightly different (see comments):
Code:
import java.util.Scanner;
class test {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = 0;
		int i=0;
		System.out.println("How many names?");
		n = sc.nextInt();
		String[] arrayString = new String[n];
		// ***Remove the request before the loop.
		for (i=0; i<n; i++) {
			System.out.println("Give the name:");
			arrayString[i] = sc.nextLine(); // ***request for input only inside the loop.
		}
		
		for (i=0; i<arrayString.length; i++) {
			System.out.println(arrayString[i]);
		}
	}
}
The second program seems more correct. But in fact if you run it it will ask you how many names? Let's say 3...
The result will be something like:

Give the name:
Give the name:
me
Give the name:
and you

me
and you

Notice that the array at the point [0] has been set to An empty string by default. The first program works fine for n=3 again:
Give the name:
Me
Give the name:
and you
Give the name:
3rd name
Me
and you
3rd name

Can anybody give me a comprehensive explanation why that happens? Because believe me.. I might solved out my problem but I still don't realize why I have to put a duplication of input over the loop.

Thanks in advance,
Cyhaxor

Last edited by Cyhaxor; 12-01-2007 at 10:25 AM.
 
Old 12-01-2007, 11:38 AM   #2
koyi
Member
 
Registered: Jul 2003
Location: Osaka, Japan
Distribution: Arch, Ubuntu
Posts: 421

Rep: Reputation: 31
I didn't check with the API so this is just a guess

I guess that sc.nextInt() only read the next integer, without bothering if there is any character, including newline(\n), following that number.

As a concrete example, say you enter "3" when you are asked to specify the number of names. This input reaches the program as "3\n". When you call sc.nextInt(), it only takes the "3" and leave the "\n" in the scanner's buffer. This "\n" will be read the next time you call sc.nextLine(), which leads to the problem in the second code.
 
Old 12-01-2007, 12:45 PM   #3
Cyhaxor
Member
 
Registered: Nov 2004
Location: UK
Distribution: Fedora 12
Posts: 129

Original Poster
Rep: Reputation: 15
Hm i don't know if you're right but your answer seems to be logic... Is there any way to change this? Because is a little annoying to put a useless scanner before the loop.. You know is a bad practice! But thanks for your answer anw!

Last edited by Cyhaxor; 12-01-2007 at 12:48 PM.
 
Old 12-01-2007, 03:32 PM   #4
Alien_Hominid
Senior Member
 
Registered: Oct 2005
Location: Lithuania
Distribution: Hybrid
Posts: 2,247

Rep: Reputation: 53
Just print your line as chars and check what was assigned to the String. Probably koyi is right.
 
Old 12-01-2007, 04:58 PM   #5
Cyhaxor
Member
 
Registered: Nov 2004
Location: UK
Distribution: Fedora 12
Posts: 129

Original Poster
Rep: Reputation: 15
yeah koyi is right but I am asking if is there any way to get the sc.nextInt(); to handle the "/n" If i do this the scanner over the loop will be non-needed. I have no problem with the program as it works fine, but is a little annoying the scanner over the loop :P

PS:And the solution is not to get the n=3 as a string and convert it to int... This would be even annoying

Last edited by Cyhaxor; 12-01-2007 at 05:06 PM.
 
Old 12-01-2007, 09:13 PM   #6
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

As koyi said, and as you now realize, the problem is that java.util.Scanner's "nextInt()" function just grabs the characters it needs (for example, "3"), leaving the rest of the line to be parsed by subsequent calls ... including the "\n", which delimits the end of the line.

One solution (since you expect a line)... is to simply ask for a line. In other words, use "nextLine()", and then convert the input:
Code:
import java.util.Scanner;

class Test {
  public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);
    System.out.print ("Enter #/names: ");
    String s = sc.nextLine ();
    int n = Integer.parseInt (s);

    System.out.println ("OK: please enter " + n + " names:");
    String[] arrayString = new String[n];
    for (int i=0; i < n; i++) {
      System.out.print ("name #" + (i+1) + ": ");
      arrayString[i] = sc.nextLine();
    }

    for (int i=0; i<arrayString.length; i++) {
      System.out.println("name[" + i + "]: " + arrayString[i]);
    }
  }
}

Last edited by paulsm4; 12-01-2007 at 09:15 PM.
 
Old 12-02-2007, 08:02 AM   #7
Cyhaxor
Member
 
Registered: Nov 2004
Location: UK
Distribution: Fedora 12
Posts: 129

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by Cyhaxor View Post
PS:And the solution is not to get the n=3 as a string and convert it to int... This would be even annoying
This would be a nice solution but it still annoying. Look I am not trying to bother you and thanks for your reply but what I am looking for is if is there any way to make the nextInt(); handle the "\n"... If isn't there any solution just tell it to me... Thanks for your support all of you!
 
Old 12-02-2007, 05:36 PM   #8
Alien_Hominid
Senior Member
 
Registered: Oct 2005
Location: Lithuania
Distribution: Hybrid
Posts: 2,247

Rep: Reputation: 53
There are InputStreamReaders, but they would be more annoying than paulsm4 solution.
 
Old 12-03-2007, 09:31 AM   #9
Cyhaxor
Member
 
Registered: Nov 2004
Location: UK
Distribution: Fedora 12
Posts: 129

Original Poster
Rep: Reputation: 15
Hm ok then, thanks for the help and ok I'll put up with java's strange behavior
 
Old 12-04-2007, 01:57 AM   #10
jay73
Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Rep: Reputation: 130Reputation: 130
Strange behaviour? So you'd actually prefer your methods to do more than they should?

Anyway, there is an alternative solution called a StreamTokenizer. It's getting to be legacy but it still comes in handy now and again. In case you wonder, a StreamTokenizer takes input and parses it by taking spaces as delimiters. It can distinguish between numbers, words and Strings but it's up to you to provide the implementation. As you can guess, it involves more coding than Scanner methods.
 
  


Reply

Tags
algorithm, array, input, java, loop, scanner


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
token bucket algorithm vs Leaky bucket algorithm xeon123 Linux - Networking 2 03-26-2007 04:57 AM
Caesar Cypher algorithm (JAVA) randomx Programming 4 10-05-2003 10:16 PM
strange java error w/ mozilla evilhomer Linux - Software 2 07-21-2003 08:03 PM
strange java font size on X leomekenkamp Linux - Software 1 07-07-2003 03:39 AM
strange java behavior neo77777 Linux - General 7 06-21-2002 01:36 AM


All times are GMT -5. The time now is 12:18 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration