Java Scanner not behaving correctly? - java

I have the following Code Snippet in my project:
public void addText(String s){
Scanner scan;
int newInt = Integer.parseInt(s.substring(s.indexOf('\t') + 1 + 1));
//find insertion point
String temp = "";
scan = new Scanner(text);
int prev = 0;
while(scan.hasNextInt() && newInt > scan.nextInt()){
temp += text.substring(prev, text.indexOf('\n')) + "\r\n";
prev = text.indexOf('\n') + 1;
}
text = temp + s + "\r\n" + text.substring(prev);
}
The goal of this is to insert a string into an existing string and keep it in a somewhat "numerical order".
The String s is a formatted string that looks like "CityName\t\tSomeNumber". That code for newInt works (confirmed by debugging). What doesn't work is the while loop. Even when text has data in it, the scan.hasNextInt() fails.
For example, assume text = "Charlestown\t\t9",s = "Downville\t\t15". newInt gets assigned 15. The while loop should iterate once and end, since 15 > 9 (were organizing cities in ascending order of these numbers). But for some reason the Scanner returns false every time on the scan.hasNextInt()part of the condition statement.
Any suggestions?

The Javadoc for hasNextInt says
Returns true if the next token in this scanner's input can be
interpreted as an int value in the default radix using the nextInt()
method. The scanner does not advance past any input.
Which means that if your next token is "Charlestown", this will return false. You're going to have to read the name of the town from your scanner before you check hasNextInt().

Related

How to Find the word that comes after a specified word in java String

My program has a String inputted Eg. hello i am john who are you oh so i see you are also john i am happy
my program then has a keyword inputted Eg. i (the program doesn't like capitals or punctuation yet)
then it reads the initial String and finds all the times it mentions the keyword + the word after the keyword, Eg. i am, i see, i am.
with this is finds the most common occurrence and outputs that second word as the new keyword and repeats. this will produce
i am john/happy (when it comes to an equal occurrence of a second word it stops (it is meant to))
What i want to know is how i find the word after the keyword.
package main;
import java.util.Scanner;
public class DeepWriterMain {
public static void main(String[] args) {
String next;
Scanner scanner = new Scanner(System.in);
System.out.println("text:");
String input = scanner.nextLine();
System.out.println("starting word:");
String start = scanner.nextLine();
input.toLowerCase();
start.toLowerCase();
if (input.contains(start)) {
System.out.println("Loading... (this is where i find the most used word after the 'start' variable)");
next = input.substring(5, 8);
System.out.println(next);
}else {
System.out.println("System has run into a problem");
}
}
}
If you use split to split all your words into an array, you can iterate through the array looking for the keyword, and if it is not the last in the array, you can print the next word
String arr [] = line.split(" ");
for (int i = 0; i < arr.length -1; i++) {
if (arr[i].equalsIgnoreCase(keyword)) {
sop(arr[i] + " " arr[i + 1]);
}
if it is not the last in the array, iterate only to length - 1
The String class includes a method called public int indexOf(String str). You could use this as follows:
int nIndex = input.indexOf(start) + start.length()
You then only need to check if nIndex == -1 in the case that start is not in the input string. Otherwise, it gets you the position of the first character of the word that follows. Using the same indexOf method to find the next space provides the end index.
This would allow you to avoid a linear search through the input, although the indexOf method probably does one anyway.

Is there a function in Java that allows you to transform a string to an Int considering the string has chars you want to ignore?

I'm doing a project for a Uni course where I need to read an input of an int followed by a '+' in the form of (for example) "2+".
However when using nextInt() it throws an InputMismatchException
What are the workarounds for this as I only want to store the int, but the "user", inputs an int followed by the char '+'?
I've already tried a lot of stuff including parseInt and valueOf but none seemed to work.
Should I just do it manually and analyze char by char?
Thanks in advance for your help.
Edit: just to clear it up. All the user will input is and Int followed by a + after. The theme of the project is to do something in the theme of a Netflix program. This parameter will be used as the age rating for a movie. However, I don't want to store the entire string in the movie as it would make things harder to check if a user is eligible or not to watch a certain movie.
UPDATE: Managed to make the substring into parseInt to work
String x = in.nextLine();
x = x.substring(0, x.length()-1);
int i = Integer.parseInt(x);
Thanks for your help :)
Try out Scanner#useDelimiter():
try(Scanner sc=new Scanner(System.in)){
sc.useDelimiter("\\D"); /* use non-digit as separator */
while(sc.hasNextInt()){
System.out.println(sc.nextInt());
}
}
Input: 2+33-599
Output:
2
33
599
OR with your current code x = x.substring(0, x.length()-1); to make it more precise try instead: x = x.replaceAll("\\D","");
Yes you should manually do it. The methods that are there will throw a parse exception. Also do you want to remove all non digit characters or just plus signs? For example if someone inputs "2 plus 5 equals 7" do you want to get 257 or throw an error? You should define strict rules.
You can do something like: Integer.parseInt(stringValue.replaceAll("[^\d]","")); to remove all characters that are no digits.
Hard way is the only way!
from my Git repo line 290.
Also useful Javadoc RegEx
It takes in an input String and extracts all numbers from it then you tokenize the string with .replaceAll() and read the tokens.
int inputLimit = 1;
Scanner scan = new Scanner(System.in);
try{
userInput = scan.nextLine();
tokens = userInput.replaceAll("[^0-9]", "");
//get integers from String input
if(!tokens.equals("")){
for(int i = 0; i < tokens.length() && i < inputLimit; ++i){
String token = "" + tokens.charAt(i);
int index = Integer.parseInt(token);
if(0 == index){
return;
}
cardIndexes.add(index);
}
}else{
System.out.println("Please enter integers 0 to 9.");
System.out.print(">");
}
Possible solutions already have been given, Here is one more.
Scanner sc = new Scanner(System.in);
String numberWithPlusSign = sc.next();
String onlyNumber = numberWithPlusSign.substring(0, numberWithPlusSign.indexOf('+'));
int number = Integer.parseInt(onlyNumber);

Changing input loop condition skips half of input values

So I wrote a program that creates a red black tree and determines the percentage of red nodes in the tree. Right now I'm making the main method for it. So here's what I have right now:
public static void main(String[] args) {
Scanner s;
if (args.length > 0){
try{
s = new Scanner(new File(args[0]));
} catch(java.io.FileNotFoundException e){
System.out.printf("Unable to open %s\n",args[0]);
return;
}
System.out.printf("Reading input values from %s.\n",args[0]);
} else {
s = new Scanner(System.in);
System.out.printf("Enter a list of non-negative integers. Enter a negative value to end the list.\n");
}
RedBlackBST<String, Integer> st = new RedBlackBST<String, Integer>();
int i = 0;
while ((s.hasNextInt())){
int key = s.nextInt();
st.put(key, i);
i++;
}
double percent = percentRed();
System.out.println("There are " + redcount + " red nodes so");
System.out.println(percent + "% of the nodes are red");
}
What I'm trying to do is create a tree based on either a file of integers (so if the user runs the program by typing "java RedBlackBST test10.txt" which would contain 10 values to insert into the tree) or if the user doesn't specify a file then it would prompt the user to type in his own values and put a negative value at the end to end the list. Right now typing in your own values don't work but if you pass in a .txt file of numbers then it works exactly as intended. Now as for typing in your own values, I was thinking of changing the while loop to look like this:
while ((s.hasNextInt()) && (s.nextInt()) >= 0){
So what this is supposed to do is go through the list of values and if you hit a negative value in the list then it stops reading the values. The problem with this is that for some reason (even if I pass in a file) it only reads half the values for any array in integers. So how come changing the while loop has now made the program only read half the array values?
Also the put method that I'm calling is the insert method which inserts the values into the tree.
Assuming you literally made the precise change you mentioned, your loop would end up looking like:
while ((s.hasNextInt()) && (s.nextInt()) >= 0){
int key = s.nextInt();
st.put(key, i);
i++;
}
Which calls nextInt() twice per iteration, which of course skips every other value, as nextInt() consumes the input.
One typical approach here is to declare key outside the loop so you have it available in the condition's scope, then assign and test it all in one go, like:
int key;
while ((s.hasNextInt()) && (key = s.nextInt()) >= 0){ // <- key is assigned *and* tested
st.put(key, i);
i++;
}
Thus, one nextInt() per iteration.

Java Scanner while loop

I'm trying to take in a string input which consists of multiple lines of numbers separated by ',' and ';' .
Example:
1,2;3,4;5,6;
9,8;7,6;
0,1;
;
Code:
ArrayList<Integer> alist = new ArrayList<>();
String delims = ";|\\,";
int i = 0;
Scanner input = new Scanner(System.in);
input.useDelimiter(delims);
while (input.hasNext()) {
alist.add(i, input.nextInt());
System.out.print(i + ' ');
System.out.print(alist.get(i) + '\n');
i++;
}
System.out.print('x');
When I run this in eclipse:
1,2;3,4;5,6; ( <= what i typed in console)
321133123413351436153716 ( <= output)
I'd expect something more like:
0 1
1 2
2 3
3 4
4 5
5 6
x
Why am I getting this sort of output?
One problem is that System.in is basically an infinite stream: hasNext will always return true unless the user enters a special command that closes it.
So you need to have the user enter something that tells you they are done. For example:
while(input.hasNext()) {
System.out.print("Enter an integer or 'end' to finish: ");
String next = input.next();
if("end".equalsIgnoreCase(next)) {
break;
}
int theInt = Integer.parseInt(next);
...
For your program, you might have the input you are trying to parse end with a special character like 1,2;3,4;5,6;end or 1,2;3,4;5,6;# that you check for.
And on these lines:
System.out.print(i + ' ');
System.out.print(alist.get(i) + '\n');
It looks like you are trying to perform String concatenation but since char is a numerical type, it performs addition instead. That is why you get the crazy output. So you need to use String instead of char:
System.out.print(i + " ");
System.out.print(alist.get(i) + "\n");
Or just:
System.out.println(i + " " + alist.get(i));
Edit for comment.
You could, for example, pull the input using nextLine from a Scanner with a default delimiter, then create a second Scanner to scan the line:
Scanner sysIn = new Scanner(System.in);
while(sysIn.hasNextLine()) {
String nextLine = sysIn.nextLine();
if(nextLine.isEmpty()) {
break;
}
Scanner lineIn = new Scanner(nextLine);
lineIn.useDelimiter(";|\\,");
while(lineIn.hasNextInt()) {
int nextInt = lineIn.nextInt();
...
}
}
Since Radiodef has already answered your actual problem(" instead of '), here are a few pointers I think could be helpful for you(This is more of a comment than an answer, but too long for an actual comment):
When you use Scanner, try to match the hasNextX function call to the nextX call. I.e. in your case, use hasNextInt and nextInt. This makes it much less likely that you will get an exception on unexpected input, while also making it easy to end input by just typing another delimiter.
Scanners useDelimiter call returns the Scanner, so it can be chained, as part of the initialisation of the Scanner. I.e. you can just write:
Scanner input = new Scanner(System.in).useDelimiter(";|\\,");
When you add to the end of an ArrayList, you don't need to(and usually should not) specify the index.
int i = 0, i++ is the textbook example of a for loop. Just because your test statement doesn't involve i does not mean you should not use a for loop.
Your code, with the above points addressed becomes as follows:
ArrayList<Integer> alist = new ArrayList<>();
Scanner input = new Scanner(System.in).useDelimiter(";|\\,");
for (int i = 0; input.hasNextInt(); i++) {
alist.add(input.nextInt());
System.out.println(i + " " + alist.get(i));
}
System.out.println('x');
Edit: Just had to mention one of my favorite delimiters for Scanner, since it is so suitable here:
Scanner input = new Scanner(System.in).useDelimiter("\\D");
This will make a Scanner over just numbers, splitting on anything that is not a number. Combined with hasNextInt it also ends input on the first blank line when reading from terminal input.

For or While loop skipping an input [duplicate]

This question already exists:
Closed 10 years ago.
Possible Duplicate:
Scanner issue when using nextLine after nextInt
I am creating a client program that needs to read both a String and an integer from my server. Depending on what integer it receives it adds some labels to the GUI. So far, my program reads the integer but skips the String. The following output is the output of my program when I try to write the integers to the program:
Server writes: 1
Server writes: 1
System prints: 1
System prints: j1
System prints: Name
The problem is that I am unable to write a String because it skips the String. How can I avoid this problem (note that I have also tried a for loop)
My code is as following:
int times = client.reciveCommando();
int o = 0;
System.out.println(times);
while (o != times) {
int j = client.reciveCommando();
System.out.println("j"+ j);
String name = client.reciveString();
System.out.println("Name " +name);
createUser(j, name);
o++;
}
The createUser method:
private void createUser(int j, String reciveChat) {
if (j == 1) {
chatPerson1.setVisible(true);
lbl_Chatperson1_userName.setVisible(true);
lbl_Chatperson1_userName.setText(reciveChat);
} else if (j == 2) {
lbl_chatPerson2.setVisible(true);
lbl_userName2.setVisible(true);
lbl_userName2.setText(reciveChat);
} else {
chatPerson3.setVisible(true);
lbl_userName3.setVisible(true);
lbl_userName3.setText(reciveChat);
}
}
The client.reciveCommando method:
public int reciveCommando() throws IOException{
Integer i = input.nextInt();
return i;
}
The client.reciveString method:
public String reciveString(){
String x = input.nextLine();
return x;
}
Hope someone is able to help me with this :)
Thank you in advance.
I don't see anywhere in the loop code where you are incrementing o or changing the value of times. So either the loop is being skipped altogether (ie: times = 0) or some other place in the code is modifying either the loop variable (o) or the loop condition (times) - very bad coding in either case.
Your loop variable/increment rules should be very clear in reading the loop and easily discernible what the start/stop conditions are without needing to read other methods/etc which may modify the values during loop iteration.
My immediate guess is that times = 0, or you would be in an endless loop.
i found the solution to my question it turned out to be quite simple!
first of all let me explain what i ment.
When i my program ran the while loop it basicly skipped the line where it should have recived an input from the server. i found that the reason it did that was that the input.nextLine(); was empty which makes sence when you read the api for input.nextLine();
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
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.
Returns:
the line that was skipped
since the line that i tried to get was an empty line it would skip and set name to " ".
here is the full complete code for my program and it currently works:
The while loop:
while (o != times) {
int j = client.reciveCommando();
System.out.println("j"+ j);
String name = client.reciveString();
System.out.println("Name " +name);
createUser(j, name);
o++;
}
The client.reciveString();
public String reciveString(){
String x = input.next();
return x;
}
The createUser();
private void createUser(int j, String reciveChat) {
if (j == 1) {
chatPerson1.setVisible(true);
lbl_Chatperson1_userName.setVisible(true);
lbl_Chatperson1_userName.setText(reciveChat);
}else if (j == 2) {
lbl_chatPerson2.setVisible(true);
lbl_userName2.setVisible(true);
lbl_userName2.setText(reciveChat);
}else if (j == 3){
chatPerson3.setVisible(true);
lbl_userName3.setVisible(true);
lbl_userName3.setText(reciveChat);}
Thank you for all of your responses and i will be sure to vote you up :)

Categories