Summing the doubles from a file - java

I've got a .txt file and here's its content:
1.1, 1.2, 1.3, 2.0, 1.8
1.3, aa, 4.5, 6.7, 2.1
3.5, 7.7, 9.9, 4.1, 2.1
I've got to load all lines from it, and if there'a double, sum it and show at the end.
I've written this program:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main3 {
public static void main(String[] args) {
File main3File = new File("Main3.txt");
double sum = 0;
try {
Scanner scan = new Scanner(main3File);
scan.useDelimiter(", ");
while (scan.hasNextLine()) {
if (scan.hasNextDouble()) {
sum += scan.nextDouble();
System.out.println(sum);
}
}
} catch (FileNotFoundException ex) {
System.out.println("Blad");
}
System.out.println("Suma: " + sum);
}
}
Here's the output:
1.1
2.3
3.5999999999996
5.6
So it sum the first three numbers, then stop and the while loop doesn't stop (if I write something under 'if', it shows without stopping). It doesn't sum the last number (1.8) and it doesn't go to the next line.
I guess it's something wrong with delimeter, right? But I don't have idea how to change it. Do you have an idea?

The main problem is you are mixing up lines and numbers, it may be better to process them separately.
If you process the lines and numbers separately, it's easier to be sure your loop condition is correct:
Scanner lineScanner = new Scanner(file);
// Loop through lines
while (lineScanner.hasNextLine()) {
String line = scan.nextLine();
Scanner numberScanner = new Scanner(line);
numberScanner.useDelimiter(", ");
// Loop through numbers in each line
while (numberScanner.hasNextFloat()) {
float value = numberScanner.nextFloat();
// do something with each value
}
System.out.println(sum);
}
If you really need to process the file in a single loop, then you need to use a delimiter that caters for the comma and any whitespace:
Scanner scan = new Scanner(main3File);
scan.useDelimiter("\\s*,\\s*");
while (scan.hasNext()) {
String next = scan.next();
try {
float value = Float.valueOf(next);
// do something with each value
} catch (NumberFormatException e) {
// not a float
}
}
\\s* is a pattern meaning 0 or more repetitions of any whitespace character.

Read one line at a time and split with comma to get the values. Check further if value is a double or not.
File main3File = new File("Main3.txt");
double sum = 0;
try {
Scanner scan = new Scanner(main3File);
String line ;
while (scan.hasNextLine()) {
line = scan.nextLine();
String[] values = line.trim().split("\\s*,\\s*");
for (String value : values) {
try {
double num = Double.parseDouble(value);
sum = sum + num;
System.out.println(sum);
} catch (NumberFormatException e) {
// System.out.println("Value is not double. hence ignored");
}
}
}
} catch (FileNotFoundException ex) {
System.out.println("Blad");
}
System.out.println("Suma: " + sum);
Let me know if you have any doubts !

1 ) Your code has a algorithm problem.
//There is a infinite loop below. You are checking next scan and handling it if it's double
//But you keep continue to loop without passing next if it is not double, this causes infinite loop
while (scan.hasNextLine()) {
if (scan.hasNextDouble()) {
sum += scan.nextDouble();
System.out.println(sum);
}
}
You have to add else statement and pass next like stated blow;
else{
scan.next();
}
2 ) You can not delimit line using
numberScanner.useDelimiter(", ");
Because you have got a multi-lined text, which scanner sees your text's end of line as a special character ("\n"). Yoo better use another way to parse, may be splitting it with String's .split method.
Hope it helps.

Related

Only allow double inputs with java scanner

import java.util.Scanner;
import java.io.*;
public class Positive {
public static void main (String args[]) {
double first;
Scanner scan = new Scanner(System.in);
System.out.print("Please enter first value" + "\n");
first= scan.nextDouble();
if (first>0.00) {
System.out.println("Please enter second value");
}
else if (first <0.00) {
first =-first;
System.out.println(first);
System.out.println("Please enter second value");
}
double second;
Scanner scaning = new Scanner(System.in);
second = scan.nextDouble();
if (first>second) {
System.out.println(first-second);
}
else if (second>first) {
System.out.println(second-first);
}
}
}
Task:
If the value is positive, request a second value. Print the difference between these two numbers so that the difference is always positive. For instance, if the first value is 10.3 and the second is 4.1, you would print the result of 6.2. If the first value is 3.8 and the second is 13.4 you would print the result 9.6.
If the first value read is negative, print its positive equivalent. For instance, if its value is –89.6 you should print 89.6.
If the first value is not a number, give appropriate error message (The standard error message from Java (e.g. “Exception in thread "main” ...”) does not count! Have a look at the Java API or Stack Overflow how to approach this).
The rest of the code runs correctly but I don't know how to only include double values in the input
By using Scanner::nextDouble you are forcing the input to only be doubles, but if you were to use Scanner::nextLine then you could then try to convert to a double and if that fails then print the message
Scanner scan = new Scanner(System.in);
System.out.println("Enter double");
String line = scan.nextLine();
double firstNum = 0.00;
try {
firstNum = Double.parseDouble(line);
}
catch (NumberFormatException e) {
System.err.println("Not a double");
}
Also, rather than doing
if (first>second) {
System.out.println(first-second);
}
else if (second>first) {
System.out.println(second-first);
}
it would be easier to do
System.out.println (Math.abs(first - second));
and also you should remove this line as it is not necessary and you are not even using it
Scanner scaning = new Scanner(System.in);

Some weird interactions are happening in my code, but I can't find a solution

My code for calculating average is correct but my program wont stop executing they way I want it to. I have to use scanner's functions in order to manipulate the string.
So I wanted to get better at Java and my tutor gave me a problem to solve. The program must accept student id, name of the subject and its marks, all in one string, and then calculate the average marks for this id. The format of the sting is "123456 math 5.5 physics 6.5 end" where the 6 digit number is the id and "end" is what makes the program stop waiting for numbers and calculate them.
ID is a 6 digit number from 0 to 9 which if it is 000000 the program must terminate.
"End" is stopping the entry but not the loop, but "000000" ends the loop.
In my code everything works fine but in order for the variables I use to reset I must type two times the word "end" and if I want to stop the loop I must type "000000" twice which is clearly not what I want. Can you point out my mistakes?
My teacher suggested to use Scanner's functions in order to get what I want. Is this problem something I cannot solve because of they way these functions work?
package averagemarks;
import java.util.*;
class AverageMarks {
public static void main(String args[]) {
String s = "123456 pr1 6.2 pr2 7.3"; //string input format
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\\s+"); //space to split string tokens
sc.useLocale(Locale.US); //with that it can recognise float numbers
int count = 0;
double sum = 0.0;
String AM; //6 numbers from 0-9 consists the student id
System.out.println("Give string: ");
while(sc.hasNext()) {
String str = sc.next();
if (sc.hasNext("[0-9]{6}")) { //this is where i check for the id which if it is 000000 it must terminate the loop
AM=str;
System.out.println("AM: " + AM);
if (AM.equals("000000")) break;
} else if(sc.hasNext()== false) { //string must end with an end if user does not end it with it i must inform him
System.out.println("Data format error.");
//return;
} else if(sc.hasNextFloat()){ //this is where i gather data for the result
sum += sc.nextFloat();
count++;
} else if(sc.hasNext("end")){ //end means that you gonna calculate all the numbers till that point then reset for another student
System.out.println("Average is " + sum / count);
count = 0;
sum = 0.0;
}
}
}
}
"In my code everything works fine"
Well, it does not!
With the line String str = sc.next(); you read away required data.
You should put it in the end to read the course name away.
while(sc.hasNext()) {
// check student id
if (sc.hasNext("[0-9]{6}")) {
AM=sc.next(); // read student number
System.out.println("AM: " + AM);
if (AM.equals("000000")) break;
}
// check if line ends prematurely --> error
else if(sc.hasNext()== false) {
System.out.println("Data format error.");
//return;
}
// check for a float
else if(sc.hasNextFloat()){
sum += sc.nextFloat(); // read the float
count++;
}
// check for "end"
else if(sc.hasNext("end")){
String endStr = sc.next(); // read "end"
System.out.println("Average is " + sum / count);
count = 0;
sum = 0.0;
}
// all other not yet considered strings (e.g. a course)
else {
String course = sc.next(); // read course
}
}
Try this:
String AM = null; //6 numbers from 0-9 consists the student id
System.out.println("Give string: ");
String str = null;
while(sc.hasNext()) {
if (sc.hasNext("[0-9]{6}"))
{
str = sc.next("[0-9]{6}");
AM = str;
System.out.println("AM: " + AM);
if (AM.equals("000000")) break;
}
else if(sc.hasNext()== false) {
System.out.println("Data format error.");
//return;
}
while(sc.hasNextDouble()){
sum += sc.nextDouble();
count++;
}
if(sc.next().equals("end")){
System.out.println("Average is " + sum / count);
count = 0;
sum = 0.0;
}
}
I did not check if your sc.hasNext()==false works, but everything else seems to working properly. Only type end once to go to next option, "000000" to end entire program. I changed the next float to next double because you had sum declared as a double and put it into a loop so it finds all the next doubles. I moved all the next operations into the conditions as well. Remember that .next() moves to the next one. Your old code with sc.hasNext("end") did not move the cursor at all. Let me know if something is off or if you have a question!

INVALID INPUT AND LOOP

T student
Im wondering if the user input a Character not an integer.How can i Show the word INVALID to him
and let him Type again.
EXAMPLE:
input a two number
a
INVALID try Again:1
2
Sum of two number=3
public static void main(String[] args) {
int x = 0, y, z;
System.out.println("Enter two integers to calculate their sum");
Scanner in = new Scanner(System.in);
try {
x = in.nextInt();
} catch (InputMismatchException e ) {
System.out.print("INVALID");
}
y = in.nextInt();
z = x + y;
System.out.println("Sum of the integers = " + z);
}
You can do for example:
while(true) {
try {
x = in.nextInt();
break;
} catch (InputMismatchException e ) {
System.out.print("INVALID try again:");
in.next(); //To wait for next value otherwise infinite loop
}
}
Basically you need to add the input into a loop and keep looping until you get valid input. You can write it in different ways but that should be the idea.
The in.next() in the catch is required because nextInt() doesn't consume the new line character of the first input and this way we skip to that.
If I were you I would use in.nextLine() for each line of parameters and the manipulate the String that I get to check for valid input instead of waiting for exception.

How would I go about using an integer delimiter? (Java)

So I am trying to read a file using a scanner. This file contains data where there are two towns, and the distance between them follows them on each line. So like this:
Ebor,Guyra,90
I am trying to get each town individual, allowing for duplicates. This is what I have so far:
// Create scanner for file for data
Scanner scanner = new Scanner(new File(file)).useDelimiter("(\\p{javaWhitespace}|\\.|,)+");
// First, count total number of elements in data set
int dataCount = 0;
while(scanner.hasNext())
{
System.out.print(scanner.next());
System.out.println();
dataCount++;
}
Right now, the program prints out each piece of information, whether it is a town name, or an integer value. Like so:
Ebor
Guyra
90
How can I make it so I have an output like this for each line:
Ebor
Guyra
Thank you!
Assuming well-formed input, just modify the loop as:
while(scanner.hasNext())
{
System.out.print(scanner.next());
System.out.print(scanner.next());
System.out.println();
scanner.next();
dataCount += 3;
}
Otherwise, if the input is not well-formed, check with hasNext() before each next() call if you need to break the loop there.
Try it that way:
Scanner scanner = new Scanner(new File(file));
int dataCount = 0;
while(scanner.hasNext())
{
String[] line = scanner.nextLine().split(",");
for(String e : line) {
if (!e.matches("-?\\d+")) System.out.println(e);;
}
System.out.println();
dataCount++;
}
}
We will go line by line, split it to array and check with regular expression if it is integer.
-? stays for negative sign, could have none or one
\\d+ stays for one or more digits
Example input:
Ebor,Guyra,90
Warsaw,Paris,1000
Output:
Ebor
Guyra
Warsaw
Paris
I wrote a method called intParsable:
public static boolean intParsable(String str)
{
int n = -1;
try
{
n = Integer.parseInt(str);
}
catch(Exception e) {}
return n != -1;
}
Then in your while loop I would have:
String input = scanner.next();
if(!intParsable(input))
{
System.out.print(input);
System.out.println();
dataCount++;
}

Java: Beginner using Scanner

I am learning Java and am learning I/O w/ java.util.Scanner. Specifically I am learning Scanner methods.
import java.util.Scanner;
public class ScannerTest {
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
int result;
while (s.hasNextInt()) {
result += s.nextInt();
}
System.out.println("The total is " + result);
}
}
Because you're checking only
while (s.hasNextInt())
You could use try catch to catch the exception (see documentation here) you get when the program quits, so you can show your error message in the catch block without making the program close.
Perhaps you should try parsing each line:
public static void main(String args[]){
int sum = 0;
final Scanner scanner = new Scanner(System.in);
System.out.println("Enter a series of integers. Press 'q' to quit.");
while(true){
final String line = scanner.nextLine();
if(line.equals("q"))
break;
try{
final int number = Integer.parseInt(line);
sum += number;
}catch(Exception ex){
System.err.printf("Invalid: %s | Try again\n", ex.getMessage());
}
}
System.out.printf("The sum is %,d" , sum);
}
The idea is to read input line by line and attempt parsing their input as an integer. If an exception is thrown (meaning they entered an invalid integer) it would throw an exception in which you could handle in what ever way you want to. In the sample above, you are simply printing the error message and prompting the user to type in another number.
You can do this for the while loop (not tested though):
while (s.hasNextLine()) {
String line = s.nextLine();
int parsedInteger;
try {
parsedInteger = Integer.parseInt(line);
} catch(NumberFormatException numEx) {
if(line.startsWith("q")) break;
else {
System.out.println("please enter valid integer or the character 'q'.");
continue;
}
}
result += parsedInteger;
}
s.close();
Instead of scanning for int's you can scan for lines and then then parse each line as an int. I feel the advantage of this approach is that if any of your int's are malformed you can then handle them appropriately by say displaying an error message to the user.
OR, based on the answer by pinckerman, you can also do this.
while (s.hasNextInt()) {
try {
result += s.nextInt();
} catch(InputMismatchException numEx) {
break;
}
}
s.close();
A smart way you can do it and I've tried before is you use Integer.parseInt(String toParse); This returns an int and will reject all non numerical chars.
while (scanner.hasNextInt()) {
int i = Integer.parseInt(scanner.nextInt());
result += i;
if (result < 2147483648 && result > -2147483648) {
try{
throw new IndexOutOfBoundsException();
catch (Exception e) {e.printStackTrace();}
}
Try the following way:
int result = input.nextInt;
this will define your variable for result.
The only problem in your code is "not initializing" result. Once you initialized code will work properly. However, please do not forget you need to tell compiler EOF. Compiler can only understand the stop of the input on the console by EOF. CTRL Z is EOF for windows Eclipse IDE.

Categories

Resources