I've recently come along this frustrating problem, where the scanner completely ignores some inputs from the System.in inputstream. Here's an example:
Do you want a cookie? Yes or no.
Now, I type yes:
yes
Result:
Cookie for you!
Now, if I say no:
no
no
Result:
No Cookie for you.
Get it? If I say yes it just accepts it. If I say no, I have to type it 2 times.
If you really need some code. Here's some of that :)
public static void main(String[] paramArgs){
MainEW sMain = new MainEW();
Scanner s = sMain.scanner;
System.out.println("Enter a file path.");
System.out.println("Example: /Users/Some_User/Desktop/Some_Folder");
String defPath = s.next();
System.out.println("Enter a name for the file.");
String defName = s.next() + ".txt";
System.out.println("Now, enter what you want to write to the file.");
s.nextLine();
String defText = s.nextLine();
System.out.println("Do you want to create a new file? Yes or No");
if (s.next().equalsIgnoreCase("yes")) {
WriterEW writer = new WriterEW(defPath, defName, defText, true);
return;
} else if (s.next().equalsIgnoreCase("no")) {
WriterEW writer = new WriterEW(defPath, defName, defText, false);
return;
} else {
System.out.println("Invalid input.");
}
}
Thanks :)
When you type "no", the else if block calls next() again, asking for more input.
Instead of calling s.next() in each case, call it just once before you start your if conditions.
String response = s.next();
if(response.equalsIgnoreCase("yes")){
WriterEW writer = new WriterEW(defPath, defName, defText, true);
return;
}else if(response.equalsIgnoreCase("no")){
Related
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 1 year ago.
I have a rudimentary piece of code that's meant to update a properties file. However, it seems that of the two possible keywords to update, only the second is updated by the user's input, as opposed to one after the other.
Here is the full code:
import java.io.*;
import java.util.Properties;
import java.util.Scanner;
public class UpdateProperty{
private static int choice;
static Scanner sc = new Scanner(System.in);
public static void main(String args[]) throws Exception
{
FileInputStream in = new FileInputStream("Stats.properties");
Properties props = new Properties(); //creates a Properties object named prop
props.load(in); //loads in as value of prop
in.close(); //no idea
System.out.println("1- BlackBerryIzzie: " + props.getProperty("BlackBerryIzzie"));
System.out.println("2- GrapeFruitIzzie: " + props.getProperty("GrapeFruitIzzie"));
System.out.println("");
String blackAmount = props.getProperty("BlackBerryIzzie");
String grapeAmount = props.getProperty("GrapeFruitIzzie");
//System.out.println("Selling BlackBerry Izzie");
//blackAmount = itemSold(blackAmount);
System.out.println("Do you wish to update inventory? Type 2");
choice = sc.nextInt();
if (choice == 2){
FileOutputStream out = new FileOutputStream("Stats.properties");
System.out.println("Insert BlackBerry Amount");
blackAmount = sc.nextLine();
props.setProperty("BlackBerryIzzie", blackAmount);
System.out.println("Insert GrapeFruit Amount");
grapeAmount = sc.nextLine();
props.setProperty("GrapeFruitIzzie", grapeAmount);
props.store(out, null);
out.close();
}
}
public static String itemSold(String s){
int i=Integer.parseInt(s);
i -= 1;
String ret=Integer.toString(i);
return ret;
}
}
The bit that seems to be malfunctioning:
if (choice == 2){
FileOutputStream out = new FileOutputStream("Stats.properties");
System.out.println("Insert BlackBerry Amount");
blackAmount = sc.nextLine();
props.setProperty("BlackBerryIzzie", blackAmount);
System.out.println("Insert GrapeFruit Amount");
grapeAmount = sc.nextLine();
props.setProperty("GrapeFruitIzzie", grapeAmount);
props.store(out, null);
out.close();
}
This is meant to ask the user for blackberry amount, then update the BlackBerryIzzie keyword to that amount. Then, it is meant to do the same for grapefruit after blackberry is done. However, it skips blackberry and only asks for one scanner input and sets grapefruit to that.
Thanks for your time!
Don't mix nextLine and nextAnythingElse.
The solution is to set your scanner's delimiter to what you want. You want 'user presses enter' to be the delimiter, surely. So, tell scanner that. Run scanner.useDelimiter("\\R") immediately after making it. Then, to get 'an entire line', call .next(), if you want that line to be read as e.g. an int, call .nextInt(), etc. Don't call nextLine() for anything.
Explaining why mixing nextLine and nextAnythingElse is bad is a bit of a story - this SO answer explains part of it. Unfortunately the 1000-vote accepted answer is not the right solution (.useDelimiter("\\R") and then .next() to read a line is the right solution).
https://courses.cs.washington.edu/courses/cse142/15sp/homework/6/spec.pdf
EDIT* Input Files are here:(sorry i'm new to stack overflow, hopefully this works)
I've also tried console.next() but it gives different errors than console.nextLine() in the rePlaceholder method. **
tarzan.txt - https://pastebin.com/XDxnXYsM
output for tarzan should look like this: https://courses.cs.washington.edu/courses/cse142/17au/homework/madlibs/expected_output_1.txt
simple.txt https://pastebin.com/Djc2R0Vz
clothes.txt https://pastebin.com/SQB8Q7Y8
this code should print to an output file you name.
Hello, I have a question about scanners because I don't understand why the code
is skipping the user input on the first iteration but works fine on the rest.
I'm writing a code to create a madlib program and the link will provide the explanation to the program but pretty much you have these placeholders in a text file and when you see one, you prompt for user input to replace it with your own words. However, my program always go through TWO placeholders first and only ask the user input for one, completely skipping the first placeholder. What is wrong with my code??? Also, how do you fix this? Everything else is running perfectly fine, only that the first line is consuming two placeholders so I'm always off by one.
Welcome to the game of Mad Libs.
I will ask you to provide various words
and phrases to fill in a story.
The result will be written to an output file.
(C)reate mad-lib, (V)iew mad-lib, (Q)uit? c
Input file name: tarzan.txt
Output file name: test.txt
Please type an adjective: Please type a plural noun: DD DDDD <--- why is it like this
Please type a noun: DDDD
Please type an adjective: DD
Please type a place:
========================================================================
package MadLibs;
import java.util.*;
import java.io.*;
public class MadLibs2 {
public static void main(String[] args) throws FileNotFoundException {
Scanner console = new Scanner(System.in);
intro();
boolean isTrue = true;
while(isTrue) {
System.out.print("(C)reate mad-lib, (V)iew mad-lib, (Q)uit? ");
String choice = console.next();
if (choice.equalsIgnoreCase("c")) {
create(console);
}
else if (choice.equalsIgnoreCase("v")) {
view(console);
}
else if (choice.equalsIgnoreCase("q")) {
System.exit(0);
}
}
}
public static void view(Scanner console) throws FileNotFoundException {
System.out.print("Input file name: ");
String viewFile = console.next();
File existingMadLib = new File(viewFile);
Scanner printText = new Scanner(existingMadLib);
while(printText.hasNextLine()) {
System.out.println(printText.nextLine());
}
}
public static void create(Scanner console) throws FileNotFoundException {
System.out.print("Input file name: ");
String inputFile = console.next();
File newMadLib = new File(inputFile);
while(!newMadLib.exists()) {
System.out.print("File not found. Try again: ");
inputFile = console.next();
newMadLib = new File(inputFile);
}
System.out.print("Output file name: ");
String outputFile = console.next();
System.out.println();
PrintStream output = new PrintStream(new File(outputFile));
Scanner input = new Scanner(newMadLib);
while(input.hasNextLine()) {
String line = input.nextLine();
outputLines(line, output, console);
}
}
public static void outputLines(String line, PrintStream output, Scanner console) throws FileNotFoundException{
String s = "";
Scanner lineScan = new Scanner(line);
while(lineScan.hasNext()){
s = lineScan.next();
if(s.startsWith("<") || s.endsWith(">")) {
s = rePlaceholder(console, lineScan, s);
}
output.print(s + " ");
}
output.println();
}
public static String rePlaceholder(Scanner console, Scanner input, String token) {
String placeholder = token;
placeholder = placeholder.replace("<", "").replace(">", "").replace("-", " ");
if (placeholder.startsWith("a") || placeholder.startsWith("e") || placeholder.startsWith("i")
|| placeholder.startsWith("o") || placeholder.startsWith("u")) {
System.out.print("Please type an " + placeholder + ": ");
} else {
System.out.print("Please type a " + placeholder + ": ");
}
String change = console.nextLine();
return change;
}
public static void intro() {
System.out.println("Welcome to the game of Mad Libs.");
System.out.println("I will ask you to provide various words");
System.out.println("and phrases to fill in a story.");
System.out.println("The result will be written to an output file.");
}
}
in your rePlaceholder, change this line:
String change = console.nextLine();
Into this
String change = console.next();
Your problem is that nextLine doesn't wait for your output, just reads what it has in the console, waiting for a new line.
This is from the documentation to be a bit more precise on the explanation:
Since this method continues to search through the input looking for a
line separator, it may buffer all of the input searching for the line
to skip if no line separators are present.
UPDATE
After reading the comment, the previous solution will not work for multiple words.
After reading the output file, you are using next().
You need to make another call to nextLine() to clean the buffer of any newlines.
System.out.print("Output file name: ");
String outputFile = console.next();
console.nextLine(); // dummy call
System.out.println();
My task is to create a program which asks the user to enter a year, a first name and a last name. It then takes the last 2 numbers of the year, the whole last name, and the first letter of the first name and formats them into an email like this: 16SmithJ#mymail.co.uk. It places this email in a text file, which doesn't need to be printed. At the end, it asks if the user wishes to repeat the process again to make a new email.
This is my program, and it isn't fully complete yet. I have it working, but when I go to implement the part which repeats it if wanted, the email is no longer made in the file:
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter (new FileWriter("7D_mail.txt"));
boolean done = false;
while (done==false){
Scanner kb = new Scanner (System.in);
System.out.print ("Enter the year (e.g 2016) > ");
String year = kb.nextLine();
System.out.print ("Enter your first name > ");
String fname = kb.nextLine();
System.out.print ("Enter your last name > ");
String lname = kb.nextLine();
pw.write (year.substring(2)+lname+fname.charAt(0)+"#mymail.co.uk");
System.out.print ("*** Email created - another one? (Y/N)");
pw.close();
}
}
This program above works, but if I then add one line after the last one (String answer = kb.nextLine();), to make a new string for the answer, it no longer works.
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter (new FileWriter("7D_mail.txt"));
boolean done = false;
while (done==false){
Scanner kb = new Scanner (System.in);
System.out.print ("Enter the year (e.g 2016) > ");
String year = kb.nextLine();
System.out.print ("Enter your first name > ");
String fname = kb.nextLine();
System.out.print ("Enter your last name > ");
String lname = kb.nextLine();
pw.write (year.substring(2)+lname+fname.charAt(0)+"#mymail.co.uk");
System.out.print ("*** Email created - another one? (Y/N)");
String answer = kb.nextLine();
pw.close();
}
}
Any idea why this doesn't work? Thanks
I don't think it stopped working. You are unconditionally setting "done" to true after you take the user's repsonse, so it exits. Wrap "done = true" in a condition that checks for the value of "answer" to be "Y".
This is because the value 'done' is set to true after the first iteration of the loop and the loop never gets a chance to run again.
Besides, you close the PrintWriter after one iteration as well.
What I would suggest is this change:
if(answer.equals("N")){
done = true;
pw.close();
}
Try using System.out.println (); after printing the question to avoid exceptions (you can read the api here https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine()).
If trying to get user input into a string, using the code:
String X = input("\nDon't just press Enter: ");
and if they did't enter anything, to ask them until they do.
I've tried to check if it's null with while(x==null) but it doesn't work. Any ideas on what I am doing wrong/need to do differently?
input() is:
static String input (String prompt)
{
String iput = null;
System.out.print(prompt);
try
{
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
iput = is.readLine();
}
catch (IOException e)
{
System.out.println("IO Exception: " + e);
}
return iput;
//return iput.toLowerCase(); //Enable for lowercase
}
In order to ask a user for an input in Java, I would recommend using the Scanner (java.util.Scanner).
Scanner input = new Scanner(System.in);
You can then use
String userInput = input.nextLine();
to retrieve the user's input. Finally, for comparing strings you should use the string.equals() method:
public String getUserInput(){
Scanner input = new Scanner(System.in);
String userInput = input.nextLine();
if (!userInput.equals("")){
//call next method
} else {
getUserInput();
}
}
What this "getUserInput" method does is to take the user's input and check that it's not blank. If it isn't blank (the first pat of the "if"), then it will continue on to the next method. However, if it is blank (""), then it will simply call the "getUserInput()" method all over again.
There are many ways to do this, but this is probably just one of the simplest ones.
I have a basic User Input and System Output program using strings, and at the start of the program it asks for the user's name, which it saves as a string variable inside the program.
Scanner input = new Scanner(System.in);
System.out.println("Hello there! What's your name?");
String name = input.nextLine();
What I want is for the program to save all new names it receives in an external file (like a
text file), and whenever a name is input it checks to see if it has encountered that name before. I want to use an if / else statement to have it display a different output depending on whether or not it has seen that name before. How do I go about accomplishing this?
~
My apologies if this is a basic problem (or if it has been answered before), but I am relatively new to java and I wasn't able to find a solution. Thank you for your help! ^-^
I think this program may accomplished your requirement
public static void main(String as[]) throws Exception{
int i=0;
File f1=new File("D:\\Name.txt");
FileWriter fw=new FileWriter(f1,true);
Scanner input = new Scanner(System.in);
Scanner output=new Scanner(f1);
System.out.println("Hello there! What's your name?");
String name = input.nextLine();
if(!f1.exists()){
f1.createNewFile();
}
else{
while(output.hasNext()){
String na=output.next();
if(na.equals(name)){
++i;
break;
}
}
if(i==0)
fw.write(name+" ");
else{
System.out.println("Please enter some different name");
}
}
fw.close();
input.close();
output.close();
}