Stop Scanner while reading Integers or String - java

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.

Related

How do you go through ArrayList and find what is in the ArrayList using Scanner?

I am making an ArrayList of cars and I am having trouble how to iterate through the ArrayList and print what I ask using a scanner.
Example: I am looking for an Audi in the list, I want it to look through the ArrayList and if it is in the ArrayList print "We have a %s."
This is what I have so far:
public class Main {
public static void main(String[] args) {
ArrayList<String> car = new ArrayList<>();
car.add("Audi");
car.add("Chevrolet");
car.add("Dodge");
car.add("Ford");
car.add("Honda");
car.add("Toyota");
car.add("Volkswagen");
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
for(String name: car)
{
if(name == sc){
System.out.printf("We have a %s.", sc);
}
}
}
}
I think that real problem here1 is that you don't have a clear understanding of what a Scanner does.
A Scanner reads characters from a stream (for example System.in) and turns them into various kinds of values; e.g. integers, floating point numbers, strings and so on. The basic model is:
call hasNextXXX to test if there is a XXX to read.
call nextXXX to read a XXX.
So you are trying to get a name of a car manufacturer from the Scanner. Assuming that car manufacturer names don't have spaces in them, what you are reading is a white-space delimited token. The method for reading a token is Scanner::next. It returns the token as a String with any leading or trailing whitespace removed.
Aside: String::nextLine would also work, except that it returns the complete line with all white space entered by the user before or after the name2. If the user enters (for example) Ford with a space after it, then that won't match the value in your car list. To deal with that, you would need to do something like this:
String str = sc.nextLine().trim(); // 'trim' removes leading and
// trailing whitespace; e.g. SP,
// TAB, CR and NL characters.
Once you have the name as a String, you should String::equals to compare it against other strings. Comparing strings using == is incorrect in nearly all circumstances; see How do I compare strings in Java?
For a deeper understanding of Scanner, I recommend that you take the time to read the javadocs.
Your code doesn't do the above. Instead, it reads a line (i.e. str = sc.nextLine()) and doesn't use it. Then it uses == to test if the Scanner is equal to each String in your list. That fails, because a Scanner is not a String.
Aside: in Java, == for a reference type (i.e. for objects) means "is this the same object".
1 - The other possibility is that you didn't read the code that you had written carefully enough.
2 - ... apart from the line separator sequence; i.e. CR, NL or CR + NL. This is removed automatically by nextLine: refer to the javadocs for more details.

print even words from string input?

I am in a beginners course but am having difficulty with the approach for the following question: Write a program that asks the user to enter a line of input. The program should then display a line containing only the even numbered words.
For example, if the user entered
I had a dream that Jake ate a blue frog,
The output should be
had dream Jake a frog
I am not sure what method to use to solve this. I began with the following, but I know that will simply return the entire input:
import java.util.Scanner;
public class HW2Q1
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a sentence");
String sentence = keyboard.next();
System.out.println();
System.out.println(sentence);
}
}
I dont want to give away the answer to the question (for the test, not here), but I suggest you look into
String.Split()
From there you would need to iterate through the results and combine in another string for output. Hope that helps.
While there will be more simpler and easier way to do this, I'll use the basic structure- for loop, if block and a while loop to achieve it. I hope you will be able to crack the code. Try running it and let me know if there is an error.
String newsent;
int i;
//declare these 2 variables
sentence.trim(); //this is important as our program runs on space
for(i=0;i<sentence.length;i++) //to skip the odd words
{
if(sentence.charAt(i)=" " && sentence.charAt(i+1)!=" ") //enters when a space is encountered after every odd word
{
i++;
while(i<sentence.length && sentence.charAt(i)!=" ") //adds the even word to the string newsent letter by letter unless a space is encountered
{
newsent=newsent + sentence.charAt(i);
i++;
}
newsent=newsent+" "; //add space at the end of even word added to the newsent
}
}
System.out.println(newsent.trim());
// removes the extra space at the end and prints newsent
you should use sentence.split(regex) the regular expression is going to describe what separate your worlds , in your case it is white space (' ') so the regex is going to be like this:
regex="[ ]+";
the [ ] means that a space will separate your words the + means that it can be a single or multiple successive white space (ie one space or more)
your code might look like this
Scanner sc= new Scanner(System.in);
String line=sc.nextLine();
String[] chunks=line.split("[ ]+");
String finalresult="";
int l=chunks.length/2;
for(int i=0;i<=l;i++){
finalresult+=chunks[i*2]+" ";//means finalresult= finalresult+chunks[i*2]+" "
}
System.out.println(finalresult);
Since you said you are a beginner, I'm going to try and use simple methods.
You could use the indexOf() method to find the indices of spaces. Then, using a while loop for the length of the sentence, go through the sentence adding every even word. To determine an even word, create an integer and add 1 to it for every iteration of the while loop. Use (integer you made)%2==0 to determine whether you are on an even or odd iteration. Concatenate the word on every even iteration (using an if statement).
If you get something like Index out of range -1, manipulate the input string by adding a space to the end.
Remember to structure the loop such that, regardless of the whether it is an even or odd iteration, the counter increases by 1.
You could alternatively remove the odd words instead of concatenation the even words, but that would be more difficult.
Not sure how you want to handle things like multiple spaces between words or weird non-alphabetically characters in the entry but this should take care of the main use case:
import java.util.Scanner;
public class HW2Q1 {
public static void main(String[] args)
{
System.out.println("Enter a sentence");
// get input and convert it to a list
Scanner keyboard = new Scanner(System.in);
String sentence = keyboard.nextLine();
String[] sentenceList = sentence.split(" ");
// iterate through the list and write elements with odd indices to a String
String returnVal = new String();
for (int i = 1; i < sentenceList.length; i+=2) {
returnVal += sentenceList[i] + " ";
}
// print the string to the console, and remove trailing whitespace.
System.out.println(returnVal.trim());
}
}

Read words until user writes 'end', then, order lexicographically(as in a dictionary), show the last word

User will enter words until the last word written is "end", then the code has to order lexicographically, as we have in a dictionary, all the words entered before 'end' and print the last word, the one classified the last.
//.....
Scanner word = new Scanner (System.in);
String keyword="end";
String finalstring;
String[] firststring= new String[1000]; //Don't know how to stablish a //dynamic string[] length, letting the user stablish the string[].length
for(int c=0;c<firststring.length;c++){
firststring[c]=word.next();
if(firststring[c].equals(keyword)){
finalstring=firststring[c].substring(0,c);
c=cadena.length-1; //To jump out of the for.
}
}
for (int c=0;c<finalstring.length();c++) {
for(int i=c+1;i<finalstring.length();i++) {
if (firststring[c].compareTo(firststring[i])>0) {
String change = firststring[c];
firststring[c] = firststring[i];
firststring[i] = change;
}
}
}
System.out.print("\nYou entered "end" and the last word classified is "+finalstring[finalstring.length()-1]); //Of course, error here, just did it to put one System.out.print of how should the result be.
}
}
This is what I tried, though, without any type of success, any help of yours will be a big help, thank you ALL!
Don't know how to stablish a dynamic string[] length, letting the user establish the string[].length
It is not necessary to do that. But here's how.
Approach #1: ask the user to give you a number and then allocate the array like this:
String[] strings = new String[theNumber];
Warning: the requirements don't say you are allowed to do that, and you may lose marks for deviating from the requirements.
Approach #2: use an ArrayList to accumulate a list of words, the use List.toArray to create an array from the list contents. (Read the javadocs for list to work it out.)
Of course, error here, just did it to put one System.out.print of how should the result be.
Yea. One problem is that the length is 1000, but you don't have 1000 actual strings in the array. The same problem affects your earlier code too. Think about is ...
I'm not going to fix your code to make it work. I've given you enough hints for you to do that for yourself. If you are prepared to put in the effort.
One more hint: you can / should use break to break out of the first loop.
I know some words are not in English but in Catalan, but the code can be perfectly understood, yesterday I finally programmed this answer:
public static void main(String[] args) {
Scanner entrada= new Scanner(System.in);
System.out.println("Escriu les paraules que vulguis, per acabar, usa la paraula 'fi'.");
String paraules = "";
int c=0;
do {
String paraula = entrada.next();
if (paraula.equals("fi")) {
c++;
} else {
if (paraula.compareTo(paraules) > 0) {
paraules = paraula;
}
}
} while (c==0);
System.out.println("L'última parala ordenada alfabèticament és "+paraules+".\n");
}
}

How do I ensure that Scanner hasNextInt() asks for new input?

New programmer here. This is probably a really basic question, but it's stumping me nevertheless.
What I'm trying to do is write a method that supplies only one integer input so I can use that input in my main program without having to mess around with non-integer inputs. However, even writing the method to do that in its own method seems to be problematic.
public static int goodInput () {
Scanner input = new Scanner (System.in); //construct scanner
boolean test = input.hasNextInt(); //set a sentinel value
while (test == false) { //enter a loop until I actually get an integer
System.out.println("Integers only please"); //tell user to give me an integer
test = input.hasNextInt(); //get new input, see if it's an integer
}
int finalInput = input.nextInt(); //once i have an integer, set it to a variable
input.close(); //closing scanner
return finalInput; //return my integer so I don't have to mess around with hasNextInt over there
}
This seems to be broken in multiple levels, but I'm not really sure why.
If I enter an integer value like 0 or 1 when I'm first asked for input, it should skip the loop entirely. But, instead, it enters the loop, and prints "Integers only please". Even worse, it doesn't actually ask for input while I'm in there, and just prints that line repeatedly.
I understand the latter problem is probably due to token issues, but I'm not necessarily sure how to solve them; closing and then reopening the scanner gets Eclipse to bug me over "duplicate objects", simply assigning the old input to a garbage String variable that is never used tells me that "No line was found" at runtime, and I'm not experienced enough to think of other ways to get new input.
Even once that's solved, I need to find some way to avoid entering the loop in the case of having an integer. I don't really understand why integer inputs inter the loop to begin with, so I'm not sure how this would be possible.
Please help? Sorry if this is an old question; tried looking at past questions but none of them seem to have the same problem that I have.
You were close: this works fine for me:
Scanner input = new Scanner(System.in); //construct scanner
while(!input.hasNextInt()) {
input.next(); // next input is not an int, so consume it and move on
}
int finalInput = input.nextInt();
input.close(); //closing scanner
System.out.println("finalInput: " + finalInput);
By calling input.next() in your while loop, you consume the non-integer content and try again, and again, until the next input is an int.
//while (test == false) { // Line #1
while (!test) { /* Better notation */ // Line #2
System.out.println("Integers only please"); // Line #3
test = input.hasNextInt(); // Line #4
} // Line #5
The problem is that in line #4 above, input.hasNextInt() only tests if an integer is inputted, and does not ask for a new integer. If the user inputs something other than an integer, hasNextInt() returns false and you cannot ask for nextInt(), because then an InputMismatchException is thrown, since the Scanner is still expecting an integer.
You must use next() instead of nextInt():
while (!input.hasNextInt()) {
input.next();
// That will 'consume' the result, but doesn't use it.
}
int result = input.nextInt();
input.close();
return result;

Java String replaceAll method having unusual affect on looping?

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.

Categories

Resources