Read only numbers from scanner - java

Imagine there is Scanner passes any String input such as "11 22 a b 22" and the method should calculate the total sum of all of the numbers (55 for the mentiond example). I've coded something here but I'm not able to skip strings. Could anyone help me with that?
System.out.println("Please enter any words and/or numbers: ");
String kbdInput = kbd.nextLine();
Scanner input = new Scanner(kbdInput);
addNumbers(input);
public static void addNumbers(Scanner input) {
double sum = 0;
while (input.hasNextDouble()) {
double nextNumber = input.nextDouble();
sum += nextNumber;
}
System.out.println("The total sum of the numbers from the file is " + sum);
}

To be able to bypass non-numeric input, you need to have your while loop look for any tokens still on the stream, not just doubles.
while (input.hasNext())
Then, inside, the while loop, see if the next token is a double with hasNextDouble. If not, you still need to consume the token with a call to next().
if (input.hasNextDouble())
{
double nextNumber = input.nextDouble();
sum += nextNumber;
}
else
{
input.next();
}

Related

Average calculator with user input Java - " java.util.NoSuchElementException: No line found "

I'm creating a simple average calculator using user input on Eclipse, and I am getting this error:
" java.util.NoSuchElementException: No line found " at
String input = sc.nextLine();
Also I think there will be follow up errors because I am not sure if I can have two variables string and float for user input.
import java.util.Scanner;
public class AverageCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the numbers you would like to average. Enter \"done\"");
String input = sc.nextLine();
float num = sc.nextFloat();
float sum = 0;
int counter = 0;
float average = 0;
while(input != "done"){
sum += num;
counter ++;
average = sum / counter;
}
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
}
}
Thanks a lot:)
First, the precision of float is just so bad that you're doing yourself a disservice using it. You should always use double unless you have a very specific need to use float.
When comparing strings, use equals(). See "How do I compare strings in Java?" for more information.
Since it seems you want the user to keep entering numbers, you need to call nextDouble() as part of the loop. And since you seem to want the user to enter text to end input, you need to call hasNextDouble() to prevent getting an InputMismatchException. Use next() to get a single word, so you can check if it is the word "done".
Like this:
Scanner sc = new Scanner(System.in);
double sum = 0;
int counter = 0;
System.out.println("Enter the numbers you would like to average. Enter \"done\"");
for (;;) { // forever loop. You could also use 'while (true)' if you prefer
if (sc.hasNextDouble()) {
double num = sc.nextDouble();
sum += num;
counter++;
} else {
String word = sc.next();
if (word.equalsIgnoreCase("done"))
break; // exit the forever loop
sc.nextLine(); // discard rest of line
System.out.println("\"" + word + "\" is not a valid number. Enter valid number or enter \"done\" (without the quotes)");
}
}
double average = sum / counter;
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
Sample Output
Enter the numbers you would like to average. Enter "done"
1
2 O done
"O" is not a valid number. Enter valid number or enter "done" (without the quotes)
0 done
The average of the 3 numbers you entered is 1.0
So there are a few issues with this code:
Since you want to have the user either enter a number or the command "done", you have to use sc.nextLine();. This is because if you use both sc.nextLine(); and sc.nextFloat();, the program will first try to receive a string and then a number.
You aren't updating the input variable in the loop, it will only ask for one input and stop.
And string comparing is weird in Java (you can't use != or ==). You need to use stra.equals(strb).
To implement the changes:
import java.util.Scanner;
public class AverageCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the numbers you would like to average. Enter \"done\"");
float sum = 0;
int counter = 0;
String input = sc.nextLine();
while (true) {
try {
//Try interpreting input as float
sum += Float.parseFloat(input);
counter++;
} catch (NumberFormatException e) {
//Turns out we were wrong!
//Check if the user entered done, if not notify them of the error!
if (input.equalsIgnoreCase("done"))
break;
else
System.out.println("'" + input + "'" + " is not a valid number!");
}
// read another line
input = sc.nextLine();
}
// Avoid a divide by zero error!
if (counter == 0) {
System.out.println("You entered no numbers!");
return;
}
// As #Andreas said in the comments, even though counter is an int, since sum is a float, Java will implicitly cast coutner to an float.
float average = sum / counter;
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
}
}
import java.util.Scanner;
public class AverageCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the numbers you would like to average. Enter \"done\" at end : ");
String input = scanner.nextLine();
float num = 0;
float sum = 0;
int counter = 0;
float average = 0;
while(!"done".equals(input)){
num = Float.parseFloat(input); // parse inside loop if its float value
sum += num;
counter ++;
average = sum / counter;
input = scanner.nextLine(); // get next input at the end
}
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
}
}

For loop to get user input lets you enter two values for the first question, but only calculates one value

I created a small program that asks the user for 10 random numbers and it will print the sum of those numbers. I embedded it with a for loop and included a counter. Everything seems to be working fine except when I run the program, the first question allows me to enter two values, but it will still only calculate a total of 10 numbers.
Below is what I currently have and I need to understand what is going wrong when it prompts the user for the number the first time:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int sum = 0;
int counter = 0;
for (int i = 0; i < 10; i++) {
counter++;
System.out.println("Enter number #" + counter + " :");
int numberInput = scanner.nextInt();
boolean hasNextInt = scanner.hasNextInt();
if (hasNextInt) {
sum += numberInput;
} else {
System.out.println("Invalid Number");
}
}
scanner.nextLine(); // handle the next line character (enter key)
System.out.println("The sum is " + sum);
scanner.close();
}
}
In each loop, you're calling scanner.nextInt() and scanner.hasNextInt(). But you do not use the result of hasNextInt() in a meaningful way (you might have noticed that your "Invalid Number" output is not what happens if you enter something that's not a number).
The first call to nextInt() blocks until you enter a number. Then hasNextInt() will block again because the number has already been read, and you're asking whether there will be a new one. This next number is read from System.in, but you're not actually using it in this iteration (you merely asked whether it's there). Then in the next iterations, nextInt() will not block because the scanner already pulled a number from System.in and can return it immediately, so all the subsequent prompts you see actually wait for input on hasNextInt().
This amounts to 11 total input events: The firts nextInt() plus all 10 hasNextInt()s
Scanner scanner = new Scanner(System.in);
int sum = 0;
int counter = 0;
for (int i = 0; i < 10; i++) {
counter++;
System.out.println("Enter number #" + counter + " :");
int numberInput = scanner.nextInt();
// boolean hasNextInt = scanner.hasNextInt();
//if (hasNextInt) {
sum += numberInput;
// } else {
// System.out.println("Invalid Number");
//}
}
scanner.nextLine(); // handle the next line character (enter key)
System.out.println("The sum is " + sum);
scanner.close();
Don't call hasnextInt() it has no use here.
It has taken 11 inputs rather than 10.
If you remove this condition it will take 10 inputs and work fine.
Your condition have no impact on it.

How to check if Scanner input is an Integer and if so, break from the loop

First off, I'm sorry if I am making a duplicate post. I tried looking for the solution and could not find it. I'm making a grade calculator where the user inputs a double "x" amount of times via a scanner. I've got the basic fundamentals of it down, and I'm not trying to fix any issues that a user might have when inputting numbers.
public static void main(String args[]) {
double total = 0;
int counter = 0;
ArrayList<String> answerYes = new ArrayList<>();
answerYes.add("yes");
answerYes.add("y");
answerYes.add("yea");
Scanner answerCheck = new Scanner(System.in);
System.out.println("Would you like to submit a number to calculate the average? [y/n]");
String userInput = answerCheck.nextLine();
while (answerYes.contains(userInput)) {
Scanner numberInput = new Scanner(System.in);
System.out.println("Please input a number: ");
Integer number = numberInput.nextInt(); //Here is where I need to check for a non-integer.
total += number;
System.out.println("Would you like to submit another number to calculate the average? [y/n]");
userInput = answerCheck.nextLine();
counter++;
}
double average = total/counter;
System.out.println("The average of those numbers is: " + average);
}
I'm pretty certain I made this more complicated than this had to be, but I wanted to test my ability to make an average calculator the way I would without the internet. Hopefully I formatted this correctly.
Thanks,
Jordan
You only need one Scanner, and you can use String.startsWith instead of checking against a collection. Something like,
double total = 0;
int counter = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Would you like to submit a number to calculate the average? [y/n]");
String userInput = scan.nextLine();
while (userInput.toLowerCase().startsWith("y")) {
System.out.println("Please input a number: ");
if (scan.hasNextInt()) {
total += scan.nextInt();
counter++;
}
scan.nextLine();
System.out.println("Would you like to submit another number to calculate the average? [y/n]");
userInput = scan.nextLine();
}
double average = total / counter;
System.out.println("The average of those numbers is: " + average);
I think what you're looking to do is something like this.
try {
int input = scanner.nextInt();
// remaining logic
} catch (InputMismatchException e) {
System.out.println("uh oh");
}
So if the user enters something which can't be read as an integer it will throw a InputMismatchException.
You could extend this by putting it in a loop forcing the user to enter a number before continuing.

Average Word Length

I am attempting to calculate the average word length of user input in Java in a very simplistic way. The actual "math" of the code I've already completed, and it seems to be working quite well, but there are some odd house keeping things I need to address in order to complete the code.
So far, I have the following:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
int count = 0;
double sum = 0;
while (sc.hasNext()) {
String userInput = sc.next();
double charNum = userInput.length();
sum = charNum + sum;
count++;
double average = 0;
if (count > 0) {
average = sum / count;
}
System.out.println("Average word length = " + average);
}
}
}
The end result output should look like this:
run:
Please type some words, then press enter:
this is a test
Average word length = 2.75
BUILD SUCCESSFUL (total time: 10 seconds)
However, the output is looking like this:
run:
Please type some words, then press enter:
this is a test
Average word length = 4.0
Average word length = 3.0
Average word length = 2.3333333333333335
Average word length = 2.75
Based on the code that I've written, how can I change it so that:
The "average word length" is only printed one final time.
The program ends after the user presses enter
Thank you for any suggestions.
You're calculating the average every single time you enter a word, which is not what you want. Also, the while loop will continue even if enter is pressed. Try this:
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
int count = 0;
double sum = 0;
String input = sc.nextLine();
String[] words = input.split("\\s+"); // split by whitespace
// iterate over each word and update the stats
for (String word : words) {
double wordLength = word.length();
sum += wordLength;
count++;
}
// calculate the average at the end
double average = 0;
if (count > 0) {
average = sum / count;
}
System.out.println("Average word length = " + average);
Output:
Please type some words, then press enter:
this is a test
Average word length = 2.75
You just need to move your System.out.println after the loop and declare average out of the loop to prevent scope issues. However, it is more elegant to do it this way :
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
double average = 0;
for (String word : sc.nextLine().split("\\s+"))
average += word.length();
average /= words.length;
System.out.println("Average word length = " + average);
sc.close();
}
}
sc.nextLine() returns the entire line typed by the user (without the last "\n" character) and split("\\s+") splits this line using the regex \s+, returning an array containing the words. This regex means to split around any non-empty sequence of blank characters.
Just get System.out.println(...) out of the while loop. And declare average variable before the loop body.
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
String words = sc.nextLine();
int count = 0;
double sum = 0;
double average = 0;
sc = new Scanner(words);
while (sc.hasNext()) {
String userInput = sc.next();
double charNum = userInput.length();
sum = charNum + sum;
count++;
if (count > 0) {
average = sum / count;
}
}
System.out.println("Average word length = " + average);
}
A) Print your output outside of the loop when all of the averaging has already been done
B) Use Date.getTime() to get the time at the start of the program after the user has inputted their sentence, and store it in a variable, then at the end of the program, get the time again, subtract it from the old time, and divide by 1000 to convert it from milliseconds to seconds. After that you can just print it out however you want it formatted
C) call sc.readLine() after you have outputted everything so that when they press enter that line will stop blocking and let the program end.

keep tracking of each token

I need to solve the following problem: Write a method named tokenStats that accepts as a parameter a Scanner containing a series of tokens. It should print out the sum of all the tokens that are legal integers, the sum of all the tokens that are legal real numbers but not integers, and the total number of tokens of any kind. For example, if a Scanner called data contains the following tokens:
3 3.14 10 squid 10.x 6.0
Then the call of tokenStats(data); should print the following output:
integers: 13
real numbers: 9.14
total tokens: 6
If the Scanner has no tokens, the method should print:
integers: 0
real numbers: 0.0
total tokens: 0
So, this is my question. I have tried to use
while (input.hasNext()) {
if (input.hasNextInt()) {
and this creates an infinite loop,
but if I use
while (input.hasNext()) {
input.next();
if (input.hasNextInt()) {
I lose my first token if it is an int...
what should I do?
I suggest you check this way .. which cover all your scenario
int totalint =0;
float totalfloat=0 ;
int count=0;
while(input.hasNext())
{
String next = input.next();
int n; float f;
try{
if(next.contains(".")
{
f= Float.parseFloat(next);
totalfloat += f;
}
else{
n= Integer.parseInt(next);
totalint +=n;
}
}
catch(Exception e){ /*not int nor a float so nothing*/ }
count++;
}
In order to determine the amount of Integers in your file I suggest doing something like this
Add the following variables to your code
ArrayList<Integer> list = new ArrayList<Integer>();
int EntryCount = 0;
int IntegerCount =0;
Then when looking through the file inputs try something like this were s is an instance of a scanner
while (s.hasNext()) {
if(s.hasNextInt() == true){
int add =s.nextInt();
System.out.println(add);
list.add(add);
IntegerCount++;
}
EntryCount++;
}
Then in order to figure out the sum of all integers you would loop through the array list.
public static void tokenStats(Scanner input) {
int integers = 0;
double real = 0.0;
int tokens = 0;
while (input.hasNext()) {
if (input.hasNextInt()) {
integers+= input.nextInt();
} else if (input.hasNextDouble()) {
real+= input.nextDouble();
} else {
input.next();
}
tokens++;
}
System.out.println("integers: " + integers);
System.out.println("real numbers: " + real);
System.out.println("total tokens: " + tokens);
}

Categories