Hey guys I am writing this program and I have a problem with this method.
public int titlesearch()
{
System.out.println("What is the title of the game you want to search for?");
String searchkey;
searchkey =input.nextLine();
String titlekey=searchkey.toLowerCase();
for (int i=0;i<gamelist.size();i++)
{
String gametitle=gamelist.get(i).getTitle();
if (gametitle.equals(titlekey) && gamelist.get(i).getSelling()== true)
{
System.out.println("Game is found!");
return i;
}
}
return -1;
}
Basically, the problem I have with it is that the first time it runs, it skips taking in user input, and it returns -1, skipping the searchkey=input.nextLine() altogether. However, if I call it a second time, it then works. What is the problem with the method?
Scanner input=new Scanner(System.in);
List<gameprofile> gamelist= new Arraylist<>();
These are the declarations for the methods above. By the way I already checked, and the entirety of the program runs but this is the only issue I have.
It should be fine the way you did it, I see no reason why your input line should be skipped. I tried it and executed it on both Windows and Linux and from command line and within eclipse, it was fine every time.
The only reason I can imagine is, that there is already something in your input buffer, but I wouldn't know why. How do you start your program and in which environment?
PS: A small remark, don't name your classes with a lower-case letter, so it should be Gameprofile or even better GameProfile instead of gameprofile.
Related
Here's the code:
private boolean getPlayerAction() {
while (player.getHandValue() < 21) {
System.out.print("Do you want to Hit or Stand?: ");
char c = getInput();
switch (c) {
case 'h' -> {
player.setCard(dealer.dealCard());
System.out.println(player.toString());
}
case 's' -> {
return true;
}
default -> System.out.println("Invalid entry, try again.");
}
}
if (player.getHandValue() > 21) {
System.out.println("Sorry. You bust.");
return false;
}
return true;
}
private char getInput() {
String input = in.nextLine();
if (!input.isEmpty()) return input.toLowerCase().charAt(0);
return 'b';
}
and here's the output:
Dealer is showing 10 with QS
You have 13 with 3H JC
It should have the prompt: "Do you want to Hit or Stand?: " where the blank line is. If I hit enter the output looks like this:
Dealer is showing 10 with QS
You have 13 with 3H JC
Do you want to Hit or Stand?: Invalid entry, try again.
Additional side note, I tried running this with println() instead of print() and it works as it should, but using print() I get the funky weirdness.
First thing I notice is that you may be well served by adding c.tolowercase() before entering the switch statement. That will guarantee that the player's choice is read in regardless of whether they type h or H (or s or S, as it may be).
I think your problem is probably in how Java handles it's System.out.print() and System.out.println() functions. It may be something to do with trying to continue your output stream with System.out.print() after it has closed the stream for that line if you used System.out.println() for your last output display (the part that tells the player their current hand)?
Unless you have a reason that you absolutely need to use .print(), I'd say just use .println() for it since you said that definitely works if you can't find a reason why .print() doesn't.
EDIT:
Maybe your issue is that .print() doesn't close the output stream, so it runs into an issue when immediately after when you try to open the input stream in what the machine sees as the middle of outputting?
You may need to flush the output to see it appear where you're hoping.
Try adding:
System.out.flush();
right after your System.out.print("Do you want to Hit or Stand?: ");
Your not showing any of the code that actually prints the statements before the print() line which is likely the code that is actually causing this issue.
Although, for your case you may need to consider calling
in.next() instead of in.nextLine() when using a print() statement instead of a println(). Thats just a guess since the other code is missing.
The code could also be optimized a lot better but, I am guessing this is some school assignment so it might not matter.
I've done HTML but that is nothing like learning java now in my AP class. So I'm pretty much brand new to coding. Today we learned about recursion and I'm pretty sure I understood it when it comes to using it like in this video.
https://www.youtube.com/watch?v=fpuWkZs51aM
But we then had to use it in a different way. We needed to make a program called WordPlay that accept any words, one at a time, until the word "STOP" is input. When stop was put in it prints them back out in reverse order. Here's the code.
import java.util.Scanner;
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Enter list of words, one per line");
System.out.println("Final word should be STOP");
wordList();
}
public static void wordList()
{
Scanner keyboard = new Scanner(System.in);
String word = keyboard.next();
if (word.equalsIgnoreCase("STOP"))
System.out.println();
else
wordList();
System.out.println(word);
}
}
So the part that I don't understand is that this works fine but when I look at the ending of wordList() it seems to me that it would just keep repeating the last word that was input. I don't get what I'm missing. Can someone explain the logic here?
The recursion does output the word that was input, however each call to wordList gets a new local variable named word (each word value is on "the stack"). If you mark it final, nothing will complain - because the word isn't modified after initialization. Also, you should probably extract the Scanner (each invocation creates a new local one of those too).
public static void wordList()
{
Scanner keyboard = new Scanner(System.in);
final String word = keyboard.next(); // <-- this is the current word.
if (word.equalsIgnoreCase("STOP"))
System.out.println();
else
wordList(); // <-- it's not STOP, recurse... which
// will get a new local word (and print it).
System.out.println(word); // <-- however, this is still current word.
}
The function will execute from top to bottom as usual, but if it enters the else block it will jump back up to the beginning like shown below. It will 'loop' exactly like this until word equals "STOP", then it'll enter the if block, print out a new line (System.out.println()) then SKIP the else block, print out word then exit the function. Brackets in the if-else statement will make this easier to see.
public static void wordList()
{
|->Scanner keyboard = new Scanner(System.in);
|
| String word = keyboard.next();
| if (word.equalsIgnoreCase("STOP")) {
| System.out.println();
| }
| else {
|---wordList();
}
System.out.println(word);
}
Its basically a recursion function or method which calls itself again and again until if condition inside it is false.
So here first new word entered by user is stored in variable called word, then if condition will check if value stored in word is Stop, if its not then again wordlist method is called and all above process is repeated again.
So each time new values entered is stored in word variable.
Thats all!!
public static int wordList()
{
Scanner keyboard = new Scanner(System.in);
String word = keyboard.next();
if (word.equalsIgnoreCase("STOP"))
{
System.out.println();
return 0;
}
System.out.println(word);
return wordList();
}
Try this
This will be the sequence of operations
1) call wordlist()
2) Get a word, say WORD1 and store in local variable word.
3) before calling wordlist recursively, WORD1 goes into stack. Stack is something like a box where you can fill say biscuits one over an other, and you can take out the biscuit that you placed last. Now the stack has WORD1
4) get another word, say WORD2 and store in local variable word. This is a new function call, even if it is recursive. So a new local variable word is allocated memory.
5) before calling wordlist recursively, WORD2 goes into stack. So now WORD2 will be the top one and WORD1 will be below in the stack.
5) get another work, now it is STOP.
6) STOP is printed
7) function returns
8) now the flow returns to previous call. Now WORD2 is popped out of stack as the local variable holding WORD2 belongs to this instance of the recursive call.
8) print WORD2 and return to previous call. Now WORD1 is popped out of the stack as the local variable holding WORD1 belongs to this instance of the recursive call
9) WORD1 printed.
Just to tell you an analogy, let us assume you have a similar task. You have to get a set of books from a friend standing besides you. You have to give him back the books in the reverse order as you got it from him as soon as he gives you a book named stop.
1) You get the book from him
2) before getting the next book, you keep it on a table, since you cannot hold this and get more books from your friend
3) yet get the next book from him
4) before getting the next book, you keep it over the first book
5) you continue doing this until you get a book named stop
6) now you start returning the books, first you will return the book named stop and as you continue, since the books are stacked, you will be returning the book in reverse order.
Hope this clarifies.
It would just repeat that last word entered if the line System.out.println(word) was before the if statement.
To understand recursion, you need the notion of the "stack". Each call to wordList() occurs in a separate level in the stack. There is a different word variable in each of these stack levels.
Since the ``System.out.println(word)` line happen after the recursive call, each of these are executed when un-piling the stack (i.e. after the previous level returns). That's why words appear in reverse order. Image: if you pile boxes one atop the other, when you un-pile them, the last box is the first to go out (hence the acronym LIFO=Last In First Out).
Another important concept for recursion is to have a way of stopping it (i.e. prevent infinite recursion). In this program, it is done when the user enters "STOP".
I like to think of these problems as a 'call stack'. Each time you 'call' the method recursively you add another 'stack'. Every recursive method needs a stopping case. In your problem the first occurrence of the word 'STOP' (how convenient) acts as your stopping case.
For example if someone enters:
"Fox"
"Bear"
"Deer"
"STOP"
As soon as the word "STOP" appears, it will be printed. Now we pick up where we left off in your 'call stack' which is the ending of
wordList()
Now the only step left is
System.out.println(word)
The word 'Deer' will be printed and now our list being printed is:
"STOP"
"Deer"
And so forth until we reach the last word.
I have a program that needs to read lines of input. It needs to be many lines at once. For example:
As I enter my time machine or
maybe not,
I wonder whether free will exists?
I wonder whether free will exists
maybe not
as I enter my time machine or.
That all gets entered at one time by the user. I was trying to use .hasNextLine() method from Scanner class, but it is not returning false.... it waits for input again. Ive been looking around for a solution and it appears that .hasNextLine() waits for input, but i do not know what alternative to use. Any suggestions? The actual code looks like:
while(input.hasNextLine());
{
line += input.nextLine();
}
Thanks for your help
Perhaps you should use some sort of "stop" sequence meaning when the user enters a particular character sequence, it will break out the loop. It might look something like:
public static void main(String args[]){
final String stopSequence = "/stop";
final Scanner reader = new Scanner(System.in);
String input = reader.nextLine();
while(!input.equalsIgnoreCase(stopSequence)){
//process input
input = reader.nextLine();
}
}
I have a class that creates multiple Integer objects and puts them into a LinkedList as shown below:
public class Shares<E> implements Queue<E> {
protected LinkedList<E> L;
public Shares() {
L = new LinkedList<E>();
}
public boolean add(E price) {
System.out.println("How many of these shares would you like?");
Scanner scanInt;
scanInt = new Scanner(System.in);
Integer noShares = scanInt.nextInt();
for (int i = 0; i < noShares; i++) {
L.addLast(price);
}
scanInt.close();
return true;
}
}
I have an application that scans for the input "add" from the console and if found, invokes the method add as shown below:
public class Application {
private static Scanner scan;
public static <E> void main(String[] args) {
Queue<Integer> S = new Shares<Integer>();
scan = new Scanner(System.in);
System.out.println("Please type add");
String sentence = scan.nextLine();
while (sentence.equals("quit") == false) {
if (sentence.equals("add")) {
System.out
.println("What price would you like to buy your shares at?");
S.add((Integer) scan.nextInt());
} else
System.exit(0);
sentence = scan.nextLine();
}
}
}
The application should allow the user to enter "add" as many times as they wish but the error "no line found" appears after the add method has been invoked.
I'm guessing this is because the Scanner in the method, has not been closed and then reopened when needed. Is this what is wrong with the program and if so, how would I go about fixing it?
Please note, this program is not finished, as I will be adding a selling method that sells these shares. That is why I am using a while loop.
Having multiple wrappers for any stream is a great way to really confuse yourself. I suggest you only ever wrap a stream once unless you really know what you are doing.
The simplest way to do this is to use a singleton in this case as it wraps another singleton (the best is to pass around the Scanner as an argument)
public class Application {
// use this Scanner in all you other code, don't create another one.
static final Scanner scan = new Scanner(System.in);
public static <E> void main(String[] args) {
Im guessing this is because the scanner in the method has not been closed
Once you close a stream it closes the underlying stream and you can't use it again. Only close System.in if you want to prevent it being used again.
how would I go about fixing it?
The best solution is to have all your Scanner use in one place, one method or one class. You have your main() do all the interaction with the user and pass the values to your data structure. Having objects which initialise themselves is a bad practice to get into and if you start doing this, it will plague you for the rest of your development days ;) (Seriously you will see this done again and again and its often a nightmare)
BTW Never exit a program without explanation. Calling System.exit(0); without even an error message is also a nightmare. I once worked on a project which has 260 calls to System.exit() often without an error message, you can imagine how much fun it is to diagnose a server just stopping for no apparent reason.
A first mistake is that this line of code
scanInt.close();
closes the System.in, not just the scanInt object. This means that after the first call to add, the scan object will only consume the input it already has and then you'll receive a NoSuchElementException: Remove this line.
Now, if you replace the last line you have with this
sentence = scan.nextLine();
System.out.println("sentence: \"" + sentence + "\"");
you will see that the last input you get before exiting is an empty String. So in the next loop you enter the else statement and your program stops execution. You can fix this problem by adding the following:
scan.nextLine(); // consume the first always empty String...
System.out.println("Please type add");
sentence = scan.nextLine(); // and then get the actual value
However, I will agree with Peter that you should not use multiple wrappers. Consider passing the Scanner object as an argument in the Shares class contractor.
Having multiple scanners (on same stream) is a very bad practice, because scanners consume the stream they share.
I've verified it while debugging the Scanner class source code, and there I’ve found:
a reference to the source input stream
a internal private buffer used to hold input.
So when a scanner instance consume its stream, basically it just read a bunch of bytes (1024) and the stream's position is moved ahead.
For example when the nextLine() method is invoket, behind the scenes the source.read() copy the result into the private buffer.
Obviously the state of other Scanner becomes corrupted (invalid).
Try to debug the Java source code yourself and/or look at the method Scanner.readInput().
thanks for reading this. I'm creating just a simple, generic version of blackjack using java. Everything else works completely fine, except when it asks you "hit or pass" and you type pass, you must type it twice for it to reconize it, and I cant seem to find out why. Heres my code on pastebin to make it easier to read: http://pastebin.com/GF7Rzusx
Relevant code from pastebin:
public void ask()
{
System.out.println("Hit or Pass?");
if (in.next().equalsIgnoreCase("Hit"))
{
hit();
}
if (in.next().equalsIgnoreCase("Pass"))
{
pass();
}
}
If the entered word is "Pass" it is read from standard input and then lost, it is not stored. It must be stored for it to be available again in the subsequent check:
String input = in.next();
if (input.equalsIgnoreCase("Hit"))
{
hit();
}
else if (input.equalsIgnoreCase("Pass"))
{
pass();
}
Surely you want:
public void ask()
{
System.out.println("Hit or Pass?");
String answer = in.next();
if (answer.equalsIgnoreCase("Hit"))
{
hit();
} else if (answer.equalsIgnoreCase("Pass"))
{
pass();
}
}
Each time you call in.next() it throws away the previous input and expects another token (input).
Example
Imagine what would happen if you had:
System.out.println(in.next());
System.out.println(in.next());
What would it expect as input and what would it output?
Main differences in code
Note that there are two differences in the new code:
You only call in.next() once and so only need one input, which is stored as answer.
You only check whether the answer is "Pass" if it wasn't already "Hit".
See Java Scanner.next documentation.
On row 112 you do:
in.next()
This will read one string token. So if you write pass, this function will return "pass".
The problem is that you do not save this value. Instead, you run in.next() again on row 116, which will require you to write pass yet again.
Instead you would like to store the string returned from in.next() on line 112.
It is because of the way the ask() method is structured. Since you have two if statements, in.next() gets called once when checking if the response is "hit", then a second time when checking for "pass". When you enter "pass", the first if statement calls next(), which returns "pass" and checks if that is equal to "hit", then moves on. Then when the second if statement calls next(), there is no next entry to return, so you have to enter "pass" again. This works when you enter "hit", however, since that is the first case checked.
Refactoring so ask only makes one call to next() should solve the problem.