Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / September 2007

Tip: Looking for answers? Try searching our database.

Still in while loop hell, Now with refined question!

Thread view: 
mmoski - 17 Sep 2007 05:17 GMT
I've refined my code to make it nice and basic.

import java.util.Scanner;

public class Parse {

    public static void main (String[] args) {

        Scanner sc = new Scanner(System.in);

        Node head = null;
        Node prev = null;
        String read = sc.next();
        Node a = new Node();

        while(sc.hasNext()){ // <-- PROBLEM AREA.

              a.data = read;

           if(head == null){
               head = a;
           }else{
               prev.next = a;
           }
           prev = a;
           read = sc.next();
       }

       for(Node pointer = head; pointer != null; pointer = pointer.next)
{
           System.out.println(pointer.data);
       }

    }
}

class Node{
    public Node next;
    public String data;
}

First off, the list has to be of my own design, so the linkedList
class is useless here.  My problem is the while loop.  I know that the
scanner usually blocks for whatever reason.  My question is, does
anybody have a suggestion for me?  If the scanner stalls waiting for
more input, how do I make it un-stall?
Patricia Shanahan - 17 Sep 2007 05:35 GMT
> First off, the list has to be of my own design, so the linkedList
> class is useless here.  My problem is the while loop.  I know that the
> scanner usually blocks for whatever reason.  My question is, does
> anybody have a suggestion for me?  If the scanner stalls waiting for
> more input, how do I make it un-stall?

By giving it more data, which does not help with the real objective of
getting your loop to finish.

Two possible solutions:

1. Provide an end-of-file, so that the Scanner will reach a hasNext()
false condition. You could do this by redirecting standard in to come
from a file, or by entering the appropriate file ending character for
the environment in which you are running.

2. Don't use end-of-file at all. Pick some other end-of-data marker, a
special data value, and make the loop continuation depend on the input
not being the end-of-data marker.

Patricia
mmoski - 17 Sep 2007 05:56 GMT
> > First off, the list has to be of my own design, so the linkedList
> > class is useless here.  My problem is the while loop.  I know that the
[quoted text clipped - 17 lines]
>
> Patricia

Perhaps if I were to use a read line to wrap the whole while and it
could reach it's EOF when it detects a blank line ie: by hitting enter
twice while in the console.  This is my next step but I fear that I'll
still stall because I don't get how the program will make it to the
next line because it has to break the nested while loop first.

Basically I want the user to type in input such as:

input one this is something
input B this is something else
hello world

I want it to read in a line and then using another while loop inside
the first I want it to then read each token in the line into a list.
In the end it should put the head node of each list into an array to
make an array of lists, which will then be processed in a certain
way.  I had this EXACT problem last year and never got a solution.  I
know that sc.next() will never return null, and that it blocks while
waiting for input.

I know what doesn't work.

What does?
blmblm@myrealbox.com - 17 Sep 2007 10:31 GMT
[ snip ]

> Perhaps if I were to use a read line to wrap the whole while and it
> could reach it's EOF when it detects a blank line ie: by hitting enter
[quoted text clipped - 19 lines]
>
> What does?

If you want to read input a line at a time, how about using a
BufferedReader?  Here's a quickly-hacked-together example of using
one to read input a line at a time, until a blank line is detected.
It compiles and runs for me, but no claims about all details being
best-practice.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class EchoUntilBlank {

   public static void main (String[] args) throws IOException {
       // probably should deal with the IOException in the code
       // rather than just throwing it, but -- quick hack for now

       BufferedReader br =
           new BufferedReader( new InputStreamReader(System.in));

       String line = null;

       while(((line = br.readLine()) != null) && (!line.equals(""))) {
           System.out.println(line); // replace with your processing
       }
   }
}

Signature

B. L. Massingill
ObDisclaimer:  I don't speak for my employers; they return the favor.

mike.mainguy@gmail.com - 18 Sep 2007 02:02 GMT
On Sep 17, 4:31 am, blm...@myrealbox.com <blm...@myrealbox.com> wrote:
> In article <1190004962.654798.105...@57g2000hsv.googlegroups.com>,
>
[quoted text clipped - 55 lines]
> B. L. Massingill
> ObDisclaimer:  I don't speak for my employers; they return the favor.

I vote for BufferedReader (or any Reader implementation for that
matter).  If the lines are all text and you really want to process
input an entire line at a time, this is really the most java-esque way
of doing it IMHO.
Lew - 18 Sep 2007 07:00 GMT
Besides all the advice on how to get a line in to your program, you have a
separate problem of how to do the loop, and how to stop it.

It is good to focus on one problem at a time.  The fact that you can gives you
the design principle to separate each problem into separate methods or
separate classes.

Many here have spoken of the way to get in a line to parse into your Node
list.   That makes it one problem, and it deserves its own method.  Let's call
that method retrieveLine().

public class NodeWorker
{
  public String retrieveLine()
  {
   String result;
   // put one of the suggested implementations here
   result = ...;
   return result;
  }
}

Actually, once you fill in that ellipsis, you've got a complete, but so far
useless class.

Get that part to compile and then add another method to do something useful,
say, create a Node from a String.

Wait!  What's a Node?  Well, it's something you add to a NodeList that holds a
String.

class Node
{
  private String data;
  private Node next;

  public String getData()
  {
    return data;
  }
  public void setData( String v )
  {
    this.data = v;
  }

  public Node getNext()
  {
    return next;
  }
  public void setNext( Node v )
  {
    this.next = v;
  }
}

What I'm showing here is to use standard get/set accessor methods for private
variables.

(If the class were generic it would be a Node<T> and you'd substitute T for
String in the class definition.)

Now you need to have an add( Node n ) method in NodeWorker.  This is where you
use that one part of your original program where you manipulate head and prev.

You really need to think about whether prev does any good yet.  Start with
just having head.

Where does head go?  In NodeWorker?

Unlike the other variables, head does not get accessor methods.
Just add( Node n ).

 // within NodeWorker
 private Node head; // don't presume to initialize it yet

 public void add( Node n )
 {
   if ( n == null )
   {
     String msg = "Let's avoid null for now, shall we?";
     throw new IllegalArgumentException( msg );
   }
   n.setNext( head );
   head = n;
 }

Notice that this handles just one eensy-weensy piece of the action.  No
worries about what the Node has for data, just a little play with the structure.

At this point you should write the main() for NodeWorker and try to get just
these methods to do something useful, perhaps watching in a debugger to see if
it does what you want.

Or anything at all.

Then add the logic to, say, parse the next token from a line and create a node
for it.  Test.

Add a loop to main() to check for a next token, then do something with it
inside the loop using the methods you've developed by that point.

Make sure to follow blmblm's advice:
> It doesn't make sense to check what hasNext() returns *after*
> making the call to next(); normal usage is to call next() only
> if hasNext() returns true.

Build it one step at time, and it'll come.

Signature

Lew

Lew - 18 Sep 2007 07:03 GMT
> Unlike the other variables, head does not get accessor methods.

Actually, you might want a getter for it eventually.  I didn't see a need for
it at first, but perhaps later.

Signature

Lew

blmblm@myrealbox.com - 17 Sep 2007 10:22 GMT
> I've refined my code to make it nice and basic.
>
[quoted text clipped - 12 lines]
>
>         while(sc.hasNext()){ // <-- PROBLEM AREA.

Yes, it is a problem, and there's one more reason (for its being
a problem) that I'm not sure anyone has pointed out yet:

It doesn't make sense to check what hasNext() returns *after*
making the call to next(); normal usage is to call next() only
if hasNext() returns true.  If you run this program and provide
it a single string as input, followed by end-of-file, the loop
will execute zero times.  As I think someone suggested in the
other thread, wouldn't it be simpler and less error-prone to write

while(sc.hasNext()) {
   String read = sc.next();
   // do stuff with read
}

rather than having two calls to next() at different points in
the program?

>                a.data = read;
>
[quoted text clipped - 25 lines]
> anybody have a suggestion for me?  If the scanner stalls waiting for
> more input, how do I make it un-stall?

Signature

B. L. Massingill
ObDisclaimer:  I don't speak for my employers; they return the favor.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.