This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes String scans acting screwy? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "String scans acting screwy?" Watch "String scans acting screwy?" New topic
Author

String scans acting screwy?

Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Hi,

I cannot get my program to scan strings correctly. I will note that this only seems to be a problem when my string scans are imbedded in If statements...I tested outside of Ifs and everything worked perfectly. There is something important that I am not understanding and I'm not getting it from anything I've researched. Here is the code:



Here is my class 'Merchandise':



When I run the program, I enter the artist, album, year, and price, but then the method returns this:

ARTIST: ALBUM: YEAR: (whatever I entered) PRICE $(whatever I entered)

The first two strings for artist and album do not return.

But...like I said...they do just fine when not embedded in the IF. Any help or insight on what Im missing is greatly appreciated.

Bill
Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
What are you trying to do with line 25? why are you storing anything that user enters into input variable?
Try This it may work:
1) Replace input on line 28 with line 29 and remove line 29.
2)Replace input on line 34 with line 35 and remove line 35.

Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Hi Rohan,

Line 25, I was really just trying to set up a short cut for inputing data. Set up a variable for say scan.nextLine() and then not have to type that every time...just type something like 'input'. Not such a good idea. I got rid of that in my code. Taking your suggestion into consideration, my code now looks like:



Doesn't compile. Error now on my first two parameters in my inputArtist object (on the 'artist' and 'album').

Bill
Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
That's because you replaced incorrectly, you only had to replace input and not the whole statement.
Now in the new program
replace line 26 with
artist=scan.nextLine();

and
line 31 with
album=scan.nextLine();
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
The problem is the initial reading in of the scans from the strings. For example.....artist = scan.nextLine();. I've been messing with them and tried everything I can think of and they just will not output correctly....although they do just fine when not embedded in an IF. I'm very frustrated...coming from someone who's specialization is in logic, the syntax should be more clear if there is an issue here.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Thanks Rohan...I might still be missing something. New code is:



But, it's a no go. Now, the compile reads:

Enter name of Artist:

Enter name of Album:

without me entering any input.

Bill
Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
Yes, now the only problem is with artist, output for album works now.
I am also not getting why is it not accepting input for artist, maybe a more experienced member will help soon.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Thanks a lot Rohan. It's something screwy about the reading Strings...per my tag. What is really funny to me is that everything works out perfectly when it is not embedded in the IF. I don't know and can't find anything on a google search. I would hate to think that I just can't do that....logic wise....
Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
Ok i got it.
Whenever we try to scan text with nextLine(); AFTER using nextInt() with the same scanner object, then java scanner does not work well.

So just create one more Scanner object and use that object to accept int values.
And now the code compiles and runs correctly.

Here is the updated code:

Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
I think your answer may be brilliantly correct...however, you never use the new Scanner object in the revised code that you give.
Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
Bill Suttle wrote:I think your answer may be brilliantly correct...however, you never use the new Scanner object in the revised code that you give.


Yes, i used it.
I created new scanner object scan1 on line 13 and used it on line 15 and 19.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Thanks Rohan
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Hi Rohan,

It worked. Awesome! I've been messing with this input string crap for two days now and couldn't get it right. Thanks BIG TIME. Now, I'm going going to study your code to understand the concept of what is going on. Thanks!

Bill

Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
Bill Suttle wrote:Hi Rohan,

the output still produces:

Name of artist:

Name of album:


at the same time...and these should be separate so user can enter data for each individually. It's what I'm getting on my compile...but I use Eclipse.


It's working correctly on my side, just copy and paste my code and see.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
It is..why I deleted that post for a 'thanks'...just didn't catch it before you caught it.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Hi Rohan, I noticed that you only use the new scan "scan1" in the choice of the IF. Can you tell me anything about your rational or the logic of your choice. It works...but I'm just not really clear on why.

Bill
Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
Bill Suttle wrote:Hi Rohan, I noticed that you only use the new scan "scan1" in the choice of the IF. Can you tell me anything about your rational or the logic of your choice. It works...but I'm just not really clear on why.

Bill


There is only one thing to know:

Don't use the same object for nextLine() after using that object with nextInt() because if you use the same object i.e. only scan in this case :
scan.nextInt() will only take integer value entered and not the \n(When we hit enter after entering the integer). So this \n is still in the buffer, so when we use scan.nextLine() after sacn.nextInt() it takes or stores \n also.That's why it was giving us the output like:
Enter name of Artist:
Enter name of Album:
when we tried the first time.
So it is better to use two different refrence variables scan and scan1 in this case.

Although this is not a rule, you can still use a single refrence variable, scan in this case.For this i think you will have to use scan.nextLine() immediately after scan.nextInt()
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Thanks Big Time Rohan!
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

I don't see any reason for two Scanners. In fact, I'm not sure it can be guaranteed to work. Just like you shouldn't have two separate InputStreams reading from the same source, I don't think you can guarantee you won't get corrupt data with two Scanners.

I'd recommend getting rid of the second Scanner. It will simplify things.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Hi Jeff,

You may have a different solution. Unfortunately the program does not run correctly without the second scanner object. I do not know if Rohan's solution can be guaranteed to always work -- which is what we require of a program, but it does work in this case and I have searched like a mad-man for a solution to the issue to no avail.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

I don't use Scanner myself, but I have never seen two Scanners used this way. I have seen a lot of people with programs very similar to yours use a single Scanner.

I would go so far as to say that using 2 is an incorrect approach, and you'd be doing yourself a favor to figure out how to make it work with 1. I would start by just getting rid of that second one, and wherever it's being used currently, use the other one. If the program doesn't work, post the exact problem.

Your call, of course, but it just looks really, really wrong to me.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
I feel exactly what you are saying Jeff...which is why I asked Rohan for a bit of explanation so far as the logic goes. Without the second scanner, the problem is exactly my initial post. I'll either get multiple println() as an output...for example

Enter Artist:

Enter Album:

Before I've entered my data for artist. Or, I can play around a bit with the nextLine()'s and will enter all of the data but the end product will be that it only outputs some of the data, for example...I enter everything and it seems to be going well, and then the method returns:

Artist: Album: Year: 1982 Price: $9.95

I'm extremely open to considering other possible solutions...Rohan's is the only that I've ran across that actually solves the issue.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Hi Jeff,

When you say that you do not use Scanner, what do you mean? How do you get keyboard input from user and assign it to a variable?
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Bill Suttle wrote:Hi Jeff,

When you say that you do not use Scanner, what do you mean? How do you get keyboard input from user and assign it to a variable?


I don't get console input that often, but when I do, I use BufferedReader.readLine().

Your program has me intrigued now. I'm going to try to look into it if I have some downtime waiting for long-running processes at work.
Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Thanks Jeff. I'll check out some documentation on BufferedReader.readLine().
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Turns out the solution is quite simple. You just need to read in the EOL sequence after each nextInt(), and you can (and should) do it using the same Scanner.

Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
Hi Jeff,

Unfortunately, that does not work. Here is my code per your suggestion:



output to console:

Enter artist....appears to read input

Enter album....appears to read input

Have to hit enter twice in order to get(which we do not want to have to hit enter twice):
Enter year....appears to read input

Enter price...appears to read input.

Then.....per method,

output does not show artist...only album, year, and price.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Bill Suttle wrote:Hi Jeff,

Unfortunately, that does not work. Here is my code per your suggestion:


The only changes I made were the ones I showed you. You added stuff that I didn't.

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

I guess I should have been more careful in my wording. When I said, "You just need to read in the EOL sequence after each nextInt()," I should have added, "...if the next use of Scanner is going to consume a line of text, but NOT if the next use of Scanner is is going to read a token like nextInt() or nextDouble()."

This is one of the subtleties I hate about Scanner.

If you have a number on one line (an int for this example, but applies to others too) and then a String on the next, you need to call:


But if you have a number on one line and then a number on the next line, you DON'T need the dummy nextLine()


The reason is this:


nextInt() reads 123
nextLine() reads \n
nextLine() reads abc\n

BUT

nextInt() reads 123
nextInt() reads \n123

That is, nexInt(), nextDouble(), etc. will consume any leading whitespace, including a newline after the last token read, but will not consume the newline after the numerical token.

There's some logic to this, but it still leads to a lot of frustration.

If you have multiple numbers on a line, separated by spaces, you can just call nextInt() multiple times to read them all. If we have "123 456", then first nextInt() will read the 123, and the next nextInt() will consume the space, ignore it, and read the "456". The newline ends up being treated the same as the space in this regard.


Bill Suttle
Ranch Hand

Joined: Oct 22, 2012
Posts: 37
That helps tremendously. I've changed the program and now everything is running perfectly...with only one Scanner object! I can't believe I've spent almost a day screwing around with this, but glad now that I have a bit deeper understand of what is going on, thanks to your help Jeff.

I am a big fan of parsimony....that extra Scanner was a quick fix but it did bug me.

Bill
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

You're welcome. Glad I was able to help.
Rohan Deshmkh
Ranch Hand

Joined: Aug 31, 2012
Posts: 127
Jeff Verdegan wrote:I don't see any reason for two Scanners. In fact, I'm not sure it can be guaranteed to work. Just like you shouldn't have two separate InputStreams reading from the same source, I don't think you can guarantee you won't get corrupt data with two Scanners.

I'd recommend getting rid of the second Scanner. It will simplify things.



yes i think using one object will simplify the things... I had mentioned this thing(use scan.nextLine() immediately after scan.nextInt() ) in my last reply.
 
wood burning stoves
 
subject: String scans acting screwy?