Java Scanner delimiter and System.in - java

I have some problem when I ask the user to input some numbers and then I want to process them. Look at the code below please.
To make this program works properly I need to input two commas at the end and then it's ok. If I dont put 2 commas at the and then program doesnt want to finish or I get an error.
Can anyone help me with this? What should I do not to input those commas at the end
package com.kurs;
import java.util.Scanner;
public class NumberFromUser {
public static void main(String[] args) {
String gd = "4,5, 6, 85";
Scanner s = new Scanner(System.in).useDelimiter(", *");
System.out.println("Input some numbers");
System.out.println("delimiter to; " + s.delimiter());
int sum = 0;
while (s.hasNextInt()) {
int d = s.nextInt();
sum = sum + d;
}
System.out.println(sum);
s.close();
System.exit(0);
}
}

Your program hangs in s.hasNextInt().
From the documentation of Scanner class:
The next() and hasNext() methods and their primitive-type companion
methods (such as nextInt() and hasNextInt()) first skip any input that
matches the delimiter pattern, and then attempt to return the next
token. Both hasNext and next methods may block waiting for further
input.
In a few words, scanner is simply waiting for more input after the last integer, cause it needs to find your delimiter in the form of the regular expression ", *" to decide that the last integer is fully typed.
You can read more about your problem in this discussion:
Link to the discussion on stackoverflow
To solve such problem, you may change your program to read the whole input string and then split it with String.split() method. Try to use something like this:
import java.util.Scanner;
public class NumberFromUser {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] tokens = sc.nextLine().split(", *");
int sum = 0;
for (String token : tokens) {
sum += Integer.valueOf(token);
}
System.out.println(sum);
}
}

Try allowing end of line to be a delimiter too:
Scanner s = new Scanner(System.in).useDelimiter(", *|[\r\n]+");

I changed your solution a bit and probably mine isn't the best one, but it seems to work:
Scanner s = new Scanner(System.in);
System.out.println("Input some numbers");
int sum = 0;
if (s.hasNextLine()) {
// Remove all blank spaces
final String line = s.nextLine().replaceAll("\\s","");
// split into a list
final List<String> listNumbers = Arrays.asList(line.split(","));
for (String str : listNumbers) {
if (str != null && !str.equals("")) {
final Integer number = Integer.parseInt(str);
sum = sum + number;
}
}
}
System.out.println(sum);

look you can do some thing like this mmm.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Input some numbers");
System.out.println("When did you to finish and get the total sum enter ,, and go");
boolean flag = true;
int sum = 0;
while (s.hasNextInt() && flag) {
int d = s.nextInt();
sum = sum + d;
}
System.out.println(sum);
}

Related

String input in java

I am trying to take string input in java using Scanner, but before that I am taking an integer input. Here is my code.
import java.util.*;
class prc
{
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
int n=input.nextInt();
for(int i=1;i<=n;i++)
{
String str=input.nextLine();
System.out.println(str);
}
}
}
The problem is that if I give a number n first, then the number of string it is taking as inputs is n-1.
e.g if the number 1 is entered first, then it is taking no string inputs and nothing is printed.
Why is this happening ?
Thanks in Advance!
nextLine() reads everything up to and including the next newline character.
However, nextInt() only reads the characters that make up the integer, and if the integer is the last (or only) text in the line, you'll be left with only the newline character.
Therefore, you'll get a blank line in the subsequent nextLine(). The solution is to call nextLine() once before the loop (and discard its result).
Information regarding the code is mentioned in the comments written next to each line.
public static void main(String[] args) {
int num1 = sc.nextInt(); //take int input
double num2 = sc.nextDouble(); //take double input
long num3 = sc.nextLong(); //take long input
float num4 = sc.nextFloat(); //take float input
sc.nextLine(); //next line will throw error if you don't use this line of code
String str = sc.nextLine(); //take String input
}
import java.util.*;
class prc
{
public static void main(String[] args)
{
String strs[];
Scanner input = new Scanner(System.in);
int n = input.nextInt();
input.nextLine();
strs = new String[n];
for(int i = 1; i < n; i++)
{
strs[i] = input.nextLine();
System.out.println(strs[i]);
}
}
}

How to make my code accepts an input

I would just like to ask on how can I make my code to just get the input instead of declaring it? Here's my program. I want to input different atomic numbers and not just "37" like what's in my code. Don't mind my comments, it's in my native language. Thanks!
public class ElectConfi {
public static void main(String s[]) {
int atomicNumber = 37;
String electronConfiguration = getElectronConfiguration(atomicNumber);
System.out.println(electronConfiguration);
}
public static String getElectronConfiguration(int atomicNumber) {
int[] config = new int[20]; //dito nag store ng number of elec. in each of the 20
orbitals.
String[] orbitals = {"1s^", "2s^", "2p^", "3s^", "3p^", "4s^", "3d^", "4p^", "5s^",
"4d^", "5p^", "6s^", "4f^", "5d^", "6p^", "7s^", "5f^", "6d^", "7p^", "8s^"};
//Names of the orbitals
String result="";
for(int i=0;i<20;i++) //dito ung i represents the orbital and tapos ung j
represents ng electrons
{
for(int j=0;(getMax(i)>j)&&(atomicNumber>0);j++,atomicNumber--) //if atomic
number > 0 and ung orbital ay kaya pa magsupport ng more electrons, add
electron to orbital ie increment configuration by 1
{
config[i]+=1;
}
if(config[i]!=0) //d2 nagche-check to prevent it printing empty
orbitals
result+=orbitals[i]+config[i]+" "; //orbital name and configuration
correspond to each other
}
return result;
}
public static int getMax(int x) //returns the number of max. supported electrons by each
orbital. for eg. x=0 ie 1s supports 2 electrons
{
if(x==0||x==1||x==3||x==5||x==8||x==11||x==15||x==19)
return 2;
else if(x==2||x==4||x==7||x==10||x==14||x==18)
return 6;
else if(x==6||x==9||x==13||x==17)
return 10;
else
return 14;
}
}
You can use either a Scanner or BufferedReader and get the user input
Using Scanner
Scanner scanner = new Scanner(System.in);
System.out.println("Please input atomic number");
int atomicNumber = scanner.nextInt();
Using BufferedReader
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int atomicNumber = Integer.parseInt(reader.readLine());
public static String getElectronConfiguration(int atomicNumber) {}
This method accepting any int value and will return String result. so you only need to provide different number as input. There is no change required in this method.
How to provide different inputs?
You can use Scanner to do that.
Scanner scanner = new Scanner(System.in);
System.out.println("Please input atomic number");
int atomicNumber = scanner.nextInt();
Now call your method
String electronConfiguration = getElectronConfiguration(atomicNumber);
What are the other ways?
You can define set of values for atomicNumber in your code and you can run those in a loop
You can get input from command line arguments by doing below :
Scanner scanner = new Scanner(System.in);
String inputLine = scanner.nextLine(); //get entire line
//or
int inputInt= scanner.nextInt();//get an integer
Check java.util.Scaner api for more info - http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
Hope this helps!
You can get the user input from a command line argument:
public static void main(String s[]) {
if (s.length == 0) {
// Print usage instructions
} else {
int atomicNumber = Integer.parseInt(s[0]);
// rest of program
}
}

ChatBot return bug

I'm working on a Chat Bot project, and I'm almost done, other than the fact that whenever I enter an input, it returns multiple outputs depending on the length of the input X.
Here is the source code:
import java.util.*;
public class ChatBot
{
public static String getResponse(String value)
{
Scanner input = new Scanner (System.in);
String X = longestWord(value);
if (value.contains("you"))
{
return "I'm not important. Let's talk about you instead.";
}
else if (X.length() <= 3)
{
return "Maybe we should move on. Is there anything else you would like to talk about?";
}
else if (X.length() == 4)
{
return "Tell me more about " + X;
}
else if (X.length() == 5)
{
return "Why do you think " + X + " is important?";
}
return "Now we are getting somewhere. How does " + X + " affect you the most?";
}
private static String longestWord(String value){
Scanner input = new Scanner (value);
String longest = new String();
"".equals(longest);
while (input.hasNext())
{
String temp = input.next();
if(temp.length() > longest.length())
{
longest = temp;
}
}
return longest;
}
}
This is for testing the Chat Bot:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.next();
}
}
}
I am also trying to modify the Bot so it counts the number of times it has responded; and also modify it so it randomly returns a random response depending on the length of the input. Any help will be much appreciated. Thank You!
You are using the Scanner.next method which only returns the next word in the string. So if you input a string with multiple words, your bot will respond to each of them.
You can use Scanner.nextLine() to get the entire input string, instead of only 1 word.
To count the number of times your bot has responded, you can create a field in the bot class:
private int responseCount = 0;
Then if you change yout getResponse method from a static method to an instance method, you can update this value from this method:
public String getResponse(String value)
{
String X = longestWord(value); //Your longestWord should also not be static.
this.responseCount++;
if (value.contains("you"))
{
...
Regarding counting the responses, just modify your main method:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
int numberOfResponses = 1;
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.nextLine();
numberOfResponses++;
}
input.close();
System.out.println(numberOfResponses);
}
}
If I have the time I will edit my post in a few minutes to check your problem regarding the double appearences of a response. You also forgot to close the Scanner.
EDIT: It actually happens because scanner has as a default the delimiter set to be on whitespace. so if you input a text with a whitespace, the while loop runs twice for one user input. Just use the nextLine() command.
Why is this code:
Scanner input = new Scanner (System.in);
In your getResponse method? Its not used at all. Take a closer look at your methods as they are holding some strange code.

Scanner only reading first set of input

This is a code I have developed to separate inputs by the block (when a space is reached):
import java.util.Scanner;
public class Single {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Three Numbers:");
String numbers = in.next();
int length = numbers.length();
System.out.println(length);
int sub = length - length;
System.out.println(sub);
System.out.println(getNumber(numbers, length, sub));
System.out.println(getNumber(numbers, length, sub));
System.out.println(getNumber(numbers, length, sub));
}
public static double getNumber(String numbers, int length, int sub){
boolean gotNumber = false;
String currentString = null;
while (gotNumber == false){
if (numbers.substring(sub, sub + 1) == " "){
sub = sub + 1;
gotNumber = true;
} else {
currentString = currentString + numbers.substring(sub, sub);
sub = sub + 1;
}
}
return Double.parseDouble(currentString);
}
}
However, it only reads the first set for the string, and ignores the rest.
How can I fix this?
The problem is here. You should replace this line
String numbers = in.next();
with this line
String numbers = in.nextLine();
because, next() can read the input only till the first space while nextLine() can read input till the newline character. For more info check this link.
If I understand the question correctly, you are only calling in.next() once. If you want to have it process the input over and over again you want a loop until you don't have any more input.
while (in.hasNext()) {
//do number processing in here
}
Hope this helps!

How to terminate Scanner when input is complete?

public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
try {
while (scan.hasNextLine()){
String line = scan.nextLine().toLowerCase();
System.out.println(line);
}
} finally {
scan.close();
}
}
Just wondering how I can terminate the program after I have completed entering the inputs?
As the scanner would still continue after several "Enter" assuming I am going to continue entering inputs...
I tried:
if (scan.nextLine() == null) System.exit(0);
and
if (scan.nextLine() == "") System.exit(0);
They did not work.... The program continues and messes with the original intention,
The problem is that a program (like yours) does not know that the user has completed entering inputs unless the user ... somehow ... tells it so.
There are two ways that the user could do this:
Enter an "end of file" marker. On UNIX and Mac OS that is (typically) CTRL+D, and on Windows CTRL+Z. That will result in hasNextLine() returning false.
Enter some special input that is recognized by the program as meaning "I'm done". For instance, it could be an empty line, or some special value like "exit". The program needs to test for this specifically.
(You could also conceivably use a timer, and assume that the user has finished if they don't enter any input for N seconds, or N minutes. But that is not a user-friendly way, and in many cases it would be dangerous.)
The reason your current version is failing is that you are using == to test for an empty String. You should use either the equals or isEmpty methods. (See How do I compare strings in Java?)
Other things to consider are case sensitivity (e.g. "exit" versus "Exit") and the effects of leading or trailing whitespace (e.g. " exit" versus "exit").
String comparison is done using .equals() and not ==.
So, try scan.nextLine().equals("").
You will have to look for specific pattern which indicates end of your input say for example "##"
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
try {
while (scan.hasNextLine()){
String line = scan.nextLine().toLowerCase();
System.out.println(line);
if (line.equals("##")) {
System.exit(0);
scan.close();
}
}
} finally {
if (scan != null)
scan.close();
}
In this case, I recommend you to use do, while loop instead of while.
Scanner sc = new Scanner(System.in);
String input = "";
do{
input = sc.nextLine();
System.out.println(input);
} while(!input.equals("exit"));
sc.close();
In order to exit program, you simply need to assign a string header e.g. exit. If input is equals to exit then program is going to exit. Furthermore, users can press control + c to exit program.
You can check the next line of input from console, and checks for your terminate entry(if any).
Suppose your terminate entry is "quit" then you should try this code :-
Scanner scanner = new Scanner(System.in);
try {
while (scanner.hasNextLine()){
// do your task here
if (scanner.nextLine().equals("quit")) {
scanner.close();
}
}
}catch(Exception e){
System.out.println("Error ::"+e.getMessage());
e.printStackTrace();
}finally {
if (scanner!= null)
scanner.close();
}
Try this code.Your terminate line should be entered by you, when you want to close/terminate the scanner.
With this approach, you have to explicitly create an exit command or an exit condition. For instance:
String str = "";
while(scan.hasNextLine() && !((str = scan.nextLine()).equals("exit")) {
//Handle string
}
Additionally, you must handle string equals cases with .equals() not ==. == compares the addresses of two strings, which, unless they're actually the same object, will never be true.
Here's how I would do it. Illustrates using a constant to limit array size and entry count, and a double divided by an int is a double produces a double result so you can avoid some casting by declaring things carefully. Also assigning an int to something declared double also implies you want to store it as a double so no need to cast that either.
import java.util.Scanner;
public class TemperatureStats {
final static int MAX_DAYS = 31;
public static void main(String[] args){
int[] dayTemps = new int[MAX_DAYS];
double cumulativeTemp = 0.0;
int minTemp = 1000, maxTemp = -1000;
Scanner input = new Scanner(System.in);
System.out.println("Enter temperatures for up to one month of days (end with CTRL/D:");
int entryCount = 0;
while (input.hasNextInt() && entryCount < MAX_DAYS)
dayTemps[entryCount++] = input.nextInt();
/* Find min, max, cumulative total */
for (int i = 0; i < entryCount; i++) {
int temp = dayTemps[i];
if (temp < minTemp)
minTemp = temp;
if (temp > maxTemp)
maxTemp = temp;
cumulativeTemp += temp;
}
System.out.println("Hi temp. = " + maxTemp);
System.out.println("Low temp. = " + minTemp);
System.out.println("Difference = " + (maxTemp - minTemp));
System.out.println("Avg temp. = " + cumulativeTemp / entryCount);
}
}
You can check if the user entered an empty by checking if the length is 0, additionally you can close the scanner implicitly by using it in a try-with-resources statement:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
System.out.println("Enter input:");
String line = "";
try (Scanner scan = new Scanner(System.in)) {
while (scan.hasNextLine()
&& (line = scan.nextLine().toLowerCase()).length() != 0) {
System.out.println(line);
}
}
System.out.println("Goodbye!");
}
}
Example Usage:
Enter input:
A
a
B
b
C
c
Goodbye!

Categories