Java String replaceAll method having unusual affect on looping? - java

I'm convinced this is a product of how the string.replaceAll() method works, but for some odd reason its making my loop run twice when you type anything with a space in it?
public class TestCode{
public static void main(String[] args) throws IOException{
Scanner scan = new Scanner(System.in);
String input = "";
while(!input.equals("X")){
System.out.println("Prompt user for input");
input = scan.next().toUpperCase();
calculatePolynomial(input);
}
}
public static void calculatePolynomial(String input){
//Clean up entry removing spaces and extracting polynomial names
String calculation = input.replaceAll("\\s", "");
System.out.println(calculation);
}
}
The idea was to have the code run... printing out the message, prompting input. Then process the input and do some stuff. Repeat the process over and over until the sentinel value 'x' is entered.
But when you type input that contains a space it, for some reason, runs the loop as if each word was now separate input. So if you enter three words, it just runs the loop three times instead of once.
I just want the user's input to be without spaces and without a nightmare of logical errors.

When using a Scanner, by default, next() tokenizes the input by whitespace. So if the user enters two words separated by whitespace, your loop will run twice.
To get the entire input in the user's input line, try using the nextLine() method instead.

Related

Stop Scanner while reading Integers or String

I'm trying to read a String and then Integers or Strings using Scanner:
public class Main {
public static void main (String[] args){
String[] StringList;
Integer[] IntegerList;
ArrayList<String> auxS = new ArrayList<>();
ArrayList<Integer> auxI = new ArrayList<>();
String order; int ord=-1;
Scanner scan = new Scanner(System.in);
order = scan.nextLine();
//do something with order
while(scan.hasNextLine()){
if(scan.hasNextInt()){
auxI.add(scan.nextInt());
}
else if(!scan.nextLine().isEmpty()){
auxS.add(scan.nextLine());
}else{ //I've tried using another scan. methods to get to this point
scan.next();
break;
}
}
}
}
As you can see, I first read a String and store it in "order", then I want to keep reading until EOF or user enters "Enter" or anything else non-specific such as "write 'exit' " or something like that.
I've tried using scan.hasNext, hasNextLine, and other combinations involving the last else but none of them worked.
If the input is:
>>THIS WILL BE STORED IN ORDER<<
123
321
213
231
312
<enter>
I want it to stop when nothing has been entered as in the last line. It is important to store the Integers or Strings in their own ArrayLists, as I use it later and I need to identify the type of each entered data (that's why I use hasNextInt inside the while loop).
Generally, just don't use .nextLine(), it is confusing and rarely does what you want. If you want to read entire lines as a single item, update the scanner's delimiter; change it from the default 'any sequence of whitespace' to 'a single newline': scanner.useDelimiter("\r?\n"); will do that (run that immediately after making a scanner). To read a line, use any of the .next() methods (but not .nextLine()): Want an int? call .nextInt(). Want any string? Call .next(), etcetera.
then split up your if/elseif block. An empty line is still a string, just, an empty one:
if (scanner.hasNextInt()) {
// deal with ints
} else {
String text = scanner.next();
if (!text.isEmpty()) {
// deal with strings
} else {
// deal with a blank line
}
}
NB: Once you stop using .nextLine(), you don't have to throw out semi-random .nextLine() calls to 'clear the buffer' or whatnot. That annoyance just goes away, which is one of the many reasons why you should just forget about nextLine. Generally, for scanners, either use only .nextLine(), or don't ever use .nextLine(), and things work out much better.

Why does scanner.hasNextInt() method need a letter to start processing numbers?

I am trying to get some integer inputs from user by using scanner.hasNextInt() method. It works just fine but I need to type a letter to let the program know that I'm done entering integers while I want the console to know that after I press the enter key after a single line.
For example, I type
(1
2
3
y
enter)
and the program works just fine but if I type
(1
2
3
enter
enter)
nothing happens, even if I keep pressing the enter key. This is the related part of my code, if you need to take a look at it.
public class Main {
static LinkedList linkedList =new LinkedList();
public static void main(String [] args){
System.out.println("enter integer numbers");
Scanner scanner=new Scanner(System.in);
while (scanner.hasNextInt()){
linkedList.append(scanner.nextInt());
}
print();
}
}
Three steps to understand it.
Scanner uses a delimiter to break the input into tokens, the default delimiter is \p{javaWhitespace}+. Try
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.delimiter());
\p{javaWhitespace} is equivalent to java.lang.Character.isWhitespace(), so \p{javaWhitespace}+ will matches multiple characters which isWhitespace.
A line break produced by key enter is a white space. When you enter multiple enters, they will be recognized as a delimiter, not a token.
You can use s single white space, so it will take the second enter as token:
scanner.useDelimiter("\\p{javaWhitespace}");

How to add a char into an array?

I have a question based on character arrays. At the moment I have an input variable that takes the first letter of the word.
char input = scanner.nextLine().charAt(0);
What I want to do is for every enter, I want to put it in an array so that I can keep a log of all the letters that have been retrievied. I am assuming this is using char[] but I am having trouble implementing added each input into the array.
char input = scanner.nextLine().charAt(0);
First thing that's unclear is what Object type is scanner?
But for now I'll assume scanner is the Scanner object from Java.util.Scanner
If that's the case scanner.nextLine() actually returns a String.
String has a charAt() method that will allow you to pick out a character anywhere in the string.
However scanner.nextLine() is getting the entire line, not just one word. So really scanner.nextLine().charAt(0) is getting the first character in the line.
scanner.next() will give you the next word in the line.
If the line contained "Hello World"
scanner.next().charAt(0) would return the character 'H'.
the next call of scanner.next().charAt(0) would then return the character 'W'
public static void main(String[] args) {
boolean finished = false;
ArrayList<Character> firstLetters = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
while (!finished) {
firstLetters.add(scanner.next().charAt(0));
}
}
The above code sample might give you the behavior you're looking for.
Please note that the while loop will run forever until finished becomes true.
Your program will have to decide when to set finished to true.
AND here's a couple of links about Java's Scanner class
tutorials point
Java Docs

Scanner nextLine, stuck in while loop or exiting at odd times

I started doing the CodeAbbey problems last night, they mentioned using stdIn since some the input data is long so copy/paste is much easier than by hand. I had never used the Scanner before so it looked easy enough. I got it working for single line inputs then I got a problem where the input was:
867955 303061
977729 180367
844485 843725
393481 604154
399571 278744
723807 596408
142116 475355
I assumed that nextLine would read each couple, xxxx yyyyy. I put the code in a while loop based on if nextLine is not empty. It runs, but I get weird output, and only after I hit return a few times.
package com.secryption;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Input: ");
Scanner scanner = new Scanner(System.in);
String input = "";
while(!(scanner.nextLine().isEmpty())) {
input = input + scanner.nextLine();
}
String[] resultSet = input.split("\\s+");
for(String s : resultSet) {
System.out.println(s);
}
}
}
I thought I might need something after adding scanner.nextLine() to input. I tried a space and that didn't help. I tried a newline and that didn't make it better.
This "should" put all the numbers in a single array, nothing special. What am I missing with scanner?
EDIT: Ok so #Luiggi Mendoza is right. I found this How to terminate Scanner when input is complete? post. So basically it it working, I just expected it to do something.
The problem is here:
while(!(scanner.nextLine().isEmpty())) {
input = input + scanner.nextLine();
}
Scanner#nextLine reads the line and will continue reading. You're reading two lines and not storing the result of the first line read, just reading and storing the results of the second.
Just change the code above to:
StringBuilder sb = new StringBuilder();
while(scanner.hasNextLine()) {
sb.append(scanner.nextLine()).append(" ");
}
hasNext() is an end of file indicator that terminates by combining keys control d on Mac ox and control z on windows pressing enter won't send the right message
to JVM

How to print characters as user inpt them in console and stop when user enters enter character java

I am trying to write a method that prints out whatever character the user is entering character by character appended with the previous ones as he enters and throws an exception when he presses enter. I have written the following code but when i enter, it appends what ever character I have written and does not throw an exception. I would appreciate your help and suggestion.
public static void inputM(StringBuffer a) throws EntExc, IOException{
char c;
String m;
while(true){
Scanner s = new Scanner(System.in);
m=s.next();
c=m.charAt(0);
if(c=='\r'){
throw new EntExc();
}
System.out.println(a.append(m));
}
}
There are a few issues here. First s.next() grabs a whitespace-delimited token and returns the entire token as a single string. Second, because Scanner uses whitespace as a delimiter, it will never return \r, it will just skip it and read the next token.
Why not use s.readLine() and simply echo the whole line? While it won't process characters as they are entered (Scanner can't really do this, it always buffers lines), it will be closer to your described requirement.

Categories

Resources