Reputation: 7
What I'm trying to do here is, I'm trying to read the numbers "1 2 3" from my text, numbers.txt
. From there, I'm trying to set it into a string variable, three. From here, I'm trying to convert it into a double so that I can use the numbers to find the average of them. I keep getting this error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "1 2 3"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:549)
at java.base/java.lang.Double.valueOf(Double.java:512)
at Main.main(Main.java:13)
I do apologize if this question has been asked in the past. I've looked into this error, as well as looking into anyone else who has asked similar questions on this website and still haven't found an answer.
Edit: I should've also added that, I have to find the average of 5 sets of numbers:
1 2 3
5 12 14 6 4 0
1 2 3 4 5 6 7 8 9 10
17
2 90 80
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Main {
public static void main(String[] args) throws FileNotFoundException , NumberFormatException {
String three;
File file = new File("numbers.txt");
Scanner in = new Scanner(file);
three = in.nextLine();
double threeconversion = Double.parseDouble(three);
System.out.println(three);
}
}
Upvotes: 0
Views: 9389
Reputation: 79620
You got the NumberFormatException
because 1 2 3
is not a string representing a double
; rather, it is a string which contains numbers.
You can read each line, split the values on whitespace, parse the values (obtained by splitting the line) into double
and find their average.
Using Stream API:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
String three;
File file = new File("numbers.txt");
Scanner in = new Scanner(file);
while (in.hasNextLine()) {
double lineAvg = Arrays.stream(in.nextLine().split("\\s+"))
.mapToDouble(Double::parseDouble)
.average()
.getAsDouble();
System.out.println(lineAvg);
}
}
}
Output:
2.0
6.833333333333333
5.5
17.0
57.333333333333336
Without using Stream API:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
String three;
File file = new File("numbers.txt");
Scanner in = new Scanner(file);
while (in.hasNextLine()) {
String line = in.nextLine();
String[] arr = line.split("\\s+");
double sum = 0;
for (String s : arr) {
sum += Double.parseDouble(s);
}
double lineAvg = sum / arr.length;
System.out.println(lineAvg);
}
}
}
Upvotes: 0
Reputation: 1116
Take this example: 1 2 3// 5 12 14 6 4 0 // 1 2 3 4 5 6 7 8 9 10// 17// 2 90 80
If there is only a space in the string, it would be easy to just split and find the average. But your string has both space and //.
There are two approaches you could do for this.
Use regex to identify numbers in your string and added them to a sum variable and then find the average. You may need to use StringBuilder if there are any double digits in the final string. Refer regex here: https://javarevisited.blogspot.com/2012/10/regular-expression-example-in-java-to-check-String-number.html#:~:text=In%20order%20to%20check%20for,Pattern%20digitPattern%20%3D%20Pattern.
Use loops and arrays to split your string two times; store the result in another array or a list; find the average from that.
I've done the 2nd way. It's a little messy but simple to understand.
Here is the code:
public static void main(String[] args) throws FileNotFoundException {
File file = new File("numbers.txt");
Scanner in = new Scanner(file);
List<Double> container = new ArrayList<>();
String[] temp1 = in.nextLine().split("//");
for (String s1 : temp1) {
String[] temp2 = s1.split(" ");
for (String s2 : temp2) {
try {
container.add(Double.parseDouble(s2));
} catch (NumberFormatException ignored) {}
}
}
double sum = 0.0;
for (double i : container) sum += i;
System.out.printf("Average: %.2f\n", sum/container.size());
}
file and in are already defined by you. container is an ArrayList to hold the final double numbers. Other variables temp1, s1, temp2, s2 are temporary arrays and string to manipulate the original string.
First I split the "//" in your string. Then I split using space. Now, since your string is not properly formatted, there will be some random empty strings form into the temporary arrays when splitting. Hence there will be error when I parse them as double. That's why there is a try-catch in the code.
Upvotes: 1
Reputation: 18255
You do:
three = in.nextLine(); // read the whole line from Scanner
double threeconversion = Double.parseDouble(three); // parse this line to double (and have NFE when line contains more than one number)
You should do following:
Scanner in = new Scanner(System.in);
in.useLocale(Locale.ENGLISH); // should be explicitly set to correctly work with decimal point
double sum = 0;
int total = 0;
while (in.hasNextDouble()) {
total++;
sum += in.nextDouble();
}
System.out.println("avg: " + (sum / total));
Upvotes: 0
Reputation: 312267
Instead of reading the entire line, you could let the Scanner
do the heavy lifting for you by use nextDouble()
:
double sum = 0.0;
int count = 0;
while (in.hasNextDouble()) {
double d = in.nextDouble();
sum += d;
count++;
}
double average = sum / count;
Upvotes: 2