Getting variable number of inputs Using Scanner in Java - java

I want to have input like:-
The first line of the input contains the two cities for where the listing of flight options must be produced – the departure city and the arrival city, separated by a white-space.
The next N lines will contain the available flights and their costs. Each line is a direct flight starting with the departure city name, followed by the arrival city name, and lastly followed by the cost of that flight – all three separate by a white-space character.
Where 1<=N<=20.
Can anyone plz help I want to know how to end the input. I am using:-
Scanner s = new Scanner(System.in);
while(!(input = s.nextLine()).equals(" "))
but all in vain.
The data is in the form of
CityA CityB // Upto its I have done. The next N lines i.e. second paragraph is a confusion
Next N lines should be in form
CityA CityC 5000
CityA CityD 3000

You can use the following code :
Scanner s = new Scanner(System.in);
int maxCount = 20;
// initialize it to a random value for now
String input = "?";
System.out.println("Enter 2 cities with cost upto 20");
while (!input.trim().equals("") && maxCount > 0) {
input = s.nextLine();
/*
* parse input accordingly
*/
maxCount--;
}
System.out.println("Done with input");

Scanner sc = new Scanner(System.in);
String input = "";
while (!(input = sc.nextLine()).equals(" ")) {
if (input.equalsIgnoreCase("EXIT")) {
break;
}
System.out.println(input);
}

Related

Why do I have to write twice to add an input in the Arraylist?

public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
Scanner input = new Scanner(System.in);
do {
System.out.println("Enter a product");
String product = input.nextLine();
arrayList.add(product);
}
while (!input.nextLine().equalsIgnoreCase("q"));
System.out.println("You wrote the following products \n");
for (String naam : arrayList) {
System.out.println(naam);
}
}
I'm trying to get some input from the user and store them into arraylist. The problem is I have to write the item twice to add an item into the list. I can't figure out why!
Instead of do-while loop use only while
while (true){
System.out.println("Enter a product");
String product = input.nextLine();
if (!product.equalsIgnoreCase("q"))
arrayList.add(product);
else
break;
}
Every time you write readLine(), a line is read. In this loop,
do {
System.out.println("Enter a product");
String product = input.nextLine();
arrayList.add(product);
}
while (!input.nextLine().equalsIgnoreCase("q"));
There are two occurrences of readLine(), so two lines are read every iteration. The first line is always added to the list and not checked against q, and the second is never added to the list, and always checked against q.
You should only do nextLine once:
while (true) {
System.out.println("Enter a product");
String product = input.nextLine(); // only this one time!
if (!product.equalsIgnoreCase("q")) {
arrayList.add(product);
} else {
break;
}
}
It happenes coz input.nextLine() makes java read the input. You should read the line and only then do the stuff:
Scanner input = new Scanner(System.in);
String product = input.nextLine();
System.out.println("Enter a product");
while (!product.equalsIgnoreCase("q")) {
arrayList.add(product);
System.out.println("Enter a product");
product = input.nextLine();
}
You can read the String values using input.next() once and have a while loop in place and read further values into your list only if the value is not equal to q.
If you have read it twice as in your case, one value is added to the list in your do part, and the value you read again in your while part is only compared to q and so to exit your code, you will be missing one value and adding another and have to give two q values one after another to exit it.
Also, since most of the other users have given there answers with nextLine instead of next you may want to check what next does and what nextLine does. In brief, if you enter names of products separated by a delimiter (default space), then with next, each value separated by the space is considered a product. Similarly, if you enter on different line as well. But, with nextLine, each line as a whole will be added as a new product. It depends on how you may want to achieve this as per your requirement.
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
Scanner input = new Scanner(System.in);
String product = input.next();
while(!product.equalsIgnoreCase("q")) {
arrayList.add(product);
product = input.next();
}
System.out.println("You wrote the following products \n");
for (String naam : arrayList) {
System.out.println(naam);
}
}

Getting and Printing User Inputs in HashMaps in Java

I stepped into Java one month ago, and have been studying then. I've come across with a problem. I need to get N number of user input pairs (key:value) to a HashMap in Java, as mentioned in below code. This gives me an InputMismatchException after entering one key:value pair. For the best of my knowledge, I can't figure out whether there is a syntax error in declared loops and assigning user input value pairs to declared HashMap. I will be really grateful if someone can elaborate this, hopefully in simple terms, as I'm a very beginner. Thank you so much for your concern.
public static void main (String [] arg){
HashMap<String, Integer> phonebook = new HashMap<>();
Scanner obj = new Scanner(System.in);
//N= Number of contacts to be entered by the user
int N = obj.nextInt();
//Getting N num of user inputs for names and contacts
while(N>0){
for (int i=0;i<N;i++)
{
//we need to input name and contact value pairs
//in same line
String name = obj.nextLine();
int contact = obj.nextInt();
//assigning user input key:value pairs to hashmap
phonebook.put(name, contact);
}
//setting key:value pairs to display
Set<String> keys = phonebook.keySet();
for(String i:keys)
{
System.out.println(i +"="+phonebook.get(i));
}
N--;
}
}
You always need to put obj.nextLine(); after you do obj.nextInt();. This is because obj.nextInt(); only consumes the number, but when you enter a number and hit the enter key, the input stream also records a newline character at the end, so the next obj.nextLine(); picks up an empty string, and you are always off by one from then on. Here's an example sequence of events:
You enter the number of inputs.
The program reads that into the variable N.
The program reads the remaining empty string into the variable name.
You enter the name.
the program tries to read a number into the variable contact, but what you entered is not a number, so it fails.
And for your own sanity, please use some indentation. Here is your corrected code, with indentation:
public static void main(String[] arg) {
HashMap<String, Integer> phonebook = new HashMap<>();
Scanner obj = new Scanner(System.in);
//N= Number of contacts to be entered by the user
int N = obj.nextInt();
obj.nextLine(); //consume the newline
//Getting N num of user inputs for names and contacts
while (N > 0) {
for (int i = 0; i < N; i++) {
//we need to input name and contact value pairs
//in same line
String name = obj.nextLine();
int contact = obj.nextInt();
obj.nextLine(); //consume the newline
//assigning user input key:value pairs to hashmap
phonebook.put(name, contact);
}
//setting key:value pairs to display
Set<String> keys = phonebook.keySet();
for (String i : keys) {
System.out.println(i + "=" + phonebook.get(i));
}
N--;
}
}
Or, if you actually want both the name and the contact to be entered on the same line as you say in the comments, you can replace this line:
String name = obj.nextLine();
With this line:
String name = obj.findInLine("\\D+");
This just tells Java to read from the input stream until it hits a digit character.
You need to add an obj.nextLine() statement after getting N. When you enter something in a prompt, there's an end-of-line character that gets added after you press enter (\n). nextInt() only reads a number, so when you call nextLine() immediately after nextInt(), it will just read the end-of-line character \n because nextInt() didn't pick it up. By adding an extra nextLine() statement after calling nextInt(), you get rid of the \n and the program can read the values properly.
This code works:
public static void main (String [] arg){
HashMap<String, Integer> phonebook = new HashMap<>();
Scanner obj = new Scanner(System.in);
//N= Number of contacts to be entered by the user
int N = obj.nextInt();
obj.nextLine();
//Getting N num of user inputs for names and contacts
while(N>0){
for (int i=0;i<N;i++)
{
//we need to input name and contact value pairs
//in same line
String name = obj.nextLine();
int contact = obj.nextInt();
obj.nextLine();
//assigning user input key:value pairs to hashmap
phonebook.put(name, contact);
}
//setting key:value pairs to display
Set<String> keys = phonebook.keySet();
for(String i:keys)
{
System.out.println(i +"="+phonebook.get(i));
}
N--;
}
}
Console input and output is below. You might want to use i < N - 1 and not i < N, because I wanted to input 2 contacts only, but had to add 3. This may confuse the user.
2
foo
100
bar
1000
bar=1000
foo=100
n
1000000
bar=1000
foo=100
n=1000000

User input for file reader

Not sure if the title will make much sense but I'm currently quite confused and not sure how to work around my problem.
I'm trying to request from the user, a destination, a max time period (in the format HH:MM) and a maximum number of changes, which so far I have done. It should then calculate each journey’s total mins along with number of changes and then compare both with the user’s criteria, I recently edited my program to use case statements.
It does link to a .txt file that has the following data in it:
York
1
60
60
Alnwick
0
130
Alnwick
2
30
20
20
So my program asks for a destination, either York or Alnwick and a number of changes, maximum time, and so on but I can't figure out how to make it work with the chosen destination, current code to follow:
import java.io.FileReader;
import java.util.Scanner;
public class InputOutput {
public static void main(String[] args) throws Exception {
// these will never change (be re-assigned)
final Scanner console = new Scanner(System.in);
final Scanner INPUT = new Scanner(new FileReader("C:\\Users\\Luke\\workspace\\Coursework\\input.txt"));
System.out.print("-- MENU -- \n");
System.out.print("1: Blahblahblah \n");
System.out.print("2: Blahblahblah \n");
System.out.print("Q: Blahblahblah \n");
System.out.print("Pick an option: ");
int option = console.nextInt();
switch(option) {
case 1 :
while(INPUT.hasNextLine()) {
System.out.println(INPUT.nextLine());
}
break;
case 2 :
System.out.print("Specify desired location: ");
String destination = console.next();
System.out.print("Specify Max Time (HH:MM): ");
String choice = console.next();
// save the index of the colon
int colon = choice.indexOf(':');
// strip the hours preceding the colon then convert to int
int givenHours = Integer.parseInt(choice.substring(0, colon));
// strip the mins following the colon then convert to int
int givenMins = Integer.parseInt(choice.substring(colon + 1, choice.length()));
// calculate the time's total mins
int maxMins = (givenHours * 60) + givenMins;
System.out.print("Specify maximum changes: ");
int maxChange = console.nextInt();
// gui spacing
System.out.println();
int mins = INPUT.nextInt();
int change = INPUT.nextInt();
if ((mins > maxMins) || (change > maxChange)) {
System.out.format("Time: %02d:%02d, Changes: %d = Unsuitable \n", (mins / 60), (mins % 60), change);
}
else {
System.out.format("Time: %02d:%02d, Changes: %d = Suitable \n", (mins / 60), (mins % 60), change);
}
//Do stuff
break;
case 3 :
default :
//Default case, reprint menu?
}
}
}
Have edited it to reduce the size of the question for StackOverflow but if more code is needed please let me know - any further help would be greatly appreciated!
You should really learn how the Scanner works:
int Scanner.nextInt() Returns the next int value that occurred in the next line.
String Scanner.next() Returns the next piece of String separated by the default delimiter which is space " ". (You could use a different Delimiter with Scanner.useDelimiter(String)). In default case this returns the next single Word.
String Scanner.nextLine() Returns the next full line separated with the "\n" Character.
So if you want to get a destination that has two words for Example "New York" and you fetch it with Scanner.next() like you do. Then you take the time the same way. You will get destination="New" and choice = "York" which is not parsable for : and will crash.
The other problem you have is that a Scanner works from start to end. So if you choose option 1 and print all the output from your input file you will reach the end and hasNextLine() == false. Means you cannot get any INPUT.nextInt() after that point. But you try when chosing option 2 after that.
Your prorgamm should start by reading in your input file into a data structure that stores all the informations for you. And get them from there in further process.
What is crashing in your code for now is that you start reading your text file with INPUT.nextInt() but the first line of your text file is York which has no Int value in it. You could repair that by adding:
[...]
System.out.println();
INPUT.nextLine(); // skips the first line which is York
int mins = INPUT.nextInt();
int change = INPUT.nextInt();
[...]

Break if Scanner reads specific input

I have a scanner that reads the input but it needs to quit when it reads 'q'.
The problem is that I can't find a way to do this.
Scanner sc = new Scanner(System.in);
System.out.println("question 1");
str1 = sc.nextLine();
System.out.println("question 2");
str2 = sc.nextLine();
System.out.println("question 3");
str3 = sc.nextLine();
The questions represents user information...
This is just an example code but it demonstrates my problem as soon as the user press q it must quit. Any ideas?
Thanks in advance!
Usually it's done like this
String input = "";
ArrayList<String> list = new ArrayList<String>();
while (!(input = scan.nextLine()).equals("q")) {
// store the input (example - you can store however you want)
list.add(input);
}
but in your case, you could also incorporate a list of questions that you can cycle through.
ArrayList<String> questions = new ArrayList<String>();
questions.add("q1");
questions.add("q2");
questions.add("q3");
Scanner scan = new Scanner(System.in);
String input = "";
ArrayList<String> userInput = new ArrayList<String>();
int index = 0;
// print the first question and increment the index
System.out.println(questions.get(index));
index++;
while (!(input = scan.nextLine()).equals("q")) {
// store the input (example - you can store however you want)
userInput.add(input);
// print the next question since the user didn't enter q
// if there are no questions left, stop asking
if (index == questions.size() - 1) {
break;
}
System.out.println(questions.get(index));
// keep track of the index!!
index++;
}
scan.close();
At the end of the question asking, you can use the values in the list of userInputs. Answers are stored starting from index 0, and correspond to the matching question list.
On a side note, if you actually wanted to detect when the user pressed "q" before he pressed enter, you could implement a KeyListener on the q button... (however, this would stop the program every time the user's valid input started with a q) see http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyListener.html for more detail
The person before me is correct, but you might also try
String input = ""
ArrayList<String> list = new ArrayList<String>();
while (true){
input = sc.nextLine();
if (input.equals("q"))
break;
list.add(input)
}
is more readable and your intentions for stopping the code are far more clear.
Hope this helps.

While loops aren't repeating

This program will read each phone number from the telephones.txt file and will check if it can be translated into one or more words of words.txt file. The output of the program will contain the telephone numbers and their word representatives. (assuming there are words and phones in the file)
public static void main(String[] args) throws IOException
{
Scanner phones = new Scanner(new File("phones.txt"));
Scanner words = new Scanner(new File("words.txt"));
PrintWriter outfile = new PrintWriter(new FileWriter("outfile.txt"));
String number = "", output = "", code = "" ;
//Scans for next phone string
while(phones.hasNext())
{
number = phones.next();
number = number.replace("-","");
//Scans for next word string
while(words.hasNext())
{
code = words.next();
char[] wordChars = null;
wordChars = code.toCharArray();
output = "";
//converts word to digits
for(char wordChar : wordChars)
{
output = output.concat(new String(convert(wordChar)));
}
if(number.equals(output));
{
System.out.println(number + " " + code);
}
break;
}
}
}
This is what I have done so far, except I can't figure out something
if(number.equals(output));
{
System.out.println(number + " " + code);
}
For this line Im trying to see if the output has the same value as the number and if it does have the same value I want to print it out however this is what happens in my program.
I tried tracing my program and this is what i think is happening but its not...
Enter first while loop while theres a phone string continue
Set number to next phone string
Enter 2nd while loop while theres a word string continue
Set code to the CURRENT word string and convert it to a digit value (assume the conversion is correct)
If converted string isn't equal to number I want to continue the loop and search for the next word. And if it is I want to display number + code and continue searching for more words.
After i search through the list of words I want to continue to the next number and repeat the search for words for that number until the first while loop has no more numbers
Answering your second issue:
After i search through the list of words I want to continue to the
next number and repeat the search for words for that number until the
first while loop has no more numbers
Answer:
You should create a new instance if scanner in each iteration, i.e. move the line:
Scanner words = new Scanner(new File("words.txt"));
into the body of the outer loop.
while(phones.hasNext())
{
Scanner words = new Scanner(new File("words.txt"));
number = phones.next();
number = number.replace("-","");
//Scans for next word string
while(words.hasNext())
{
...
}
}
Your inner loop always ends on a break. So the loop body will only ever get executed once. Just put your break into the block that describes the handling of a successful phone number match.

Categories

Resources