Program asks for the name of a file. I have a file and trying to read data from it(contains only doubles) and then print the mean to an output file.
After looping through the file, I calculate and store the mean, which is stored in Results.txt. But, my local variables are underlined and my IDE says they are reassigned. Why? They are initialized and within the same method. Everything else in the code works, including the loop. I can't figure out why the mean isn't being sent to the file.
public class FileDemo {
public static void main(String[] args) throws IOException {
double sum = 0;
int count = 0;
double mean = 0; //The average of the numbers
double stdDev = 0; //The standard deviation
// Create an object of type Scanner
Scanner keyboard = new Scanner(System.in);
String filename;
// User input and read file name
System.out.println("This program calculates stats on a file.");
System.out.print("Enter the file name: ");
filename = keyboard.nextLine();
//Create a PrintWriter object passing it the filename Results.txt
//FileWriter f = new FileWriter("Results.txt");
PrintWriter outputFile = new PrintWriter("Results.txt");
//Print the mean and standard deviation to the output file using a three decimal format
outputFile.printf("Mean: %.3f\n", mean);
outputFile.printf("Standard Deviation: %.3f\n", stdDev);
//Close the output file
outputFile.close();
//read from input file
File file2 = new File(filename);
Scanner inputFile = new Scanner(file2);
// Loop until you are at the end of the file
while(inputFile.hasNext()){
double number = inputFile.nextDouble();
sum += number;
count++;
}
inputFile.close();
mean = sum / count;
}
}
sum, count, are flagged as reassigned variables.
mean is flagged as 'The value sum / count assigned to 'mean' is never used'
mean is flagged as 'The value sum / count assigned to 'mean' is never used'
This is exactly what it says. You do mean = sum / count; but you never use the value assigned to mean after this calculation. It looks like you have
outputFile.printf("Mean: %.3f\n", mean);
But remember that Java executes statements in order, so this will always print out 0.000. To fix this, you need to calculate the mean before writing it to the file.
Related
I need to pull integers from a text file and sum them up. I came up with this but I keep getting an error. What am I missing? I need to use a scanner class.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class txtClass {
public static void main(String[] args) throws FileNotFoundException {
File txtFile = new File(//text file path//);
Scanner scan = new Scanner(txtFile);
int length = 0;
while(scan.hasNextLine()) {
scan.nextLine();
length++;
}
int array[] = new int [length];
array[length++] = scan.nextInt();
System.out.println(array.toString());
int h = 0;
for (int i = 0; i<array.length; i++)
{
h +=array[i];
}
scan.close();
System.out.print(h);
}
}
As suggested, a lot of the code is not really needed. But presumably the 'error' you get is array index out of bounds. Here:
int array[] = new int [length];
array[length++] = scan.nextInt();
So you allocate an array and immediately access off the end of the array. Let's assume length is 42. Therefore, the allocated array elements have indexes 0 to 41. You try and assign something to array[42]. I'm not sure what you're trying to do with that line.
The alternative guess (which we would not need to guess had you mentioned the actual error message) is that your counting lines leaves the scanner positioned at end of file. so the scan.nextInt() call in the assignment gets you an I/O error.
In any case, the core of the solution is something like
int sum = 0;
while (scan.hasNextInt())
sum += scan.nextInt();
No array is needed.
You wrote in your question
I keep getting an error
That would be NoSuchElementException which is thrown by this line of your code:
array[length++] = scan.nextInt();
This is because you have already scanned the entire file and therefore there is no next int.
Remember that in order for people to help you with errors thrown by your code, you need to post the actual exception and the stack trace as well as your code.
You don't need to save all the numbers in the file in an array in order to get the sum of all the numbers. However if you also want to save all the numbers but you don't know in advance how many there are, you can use a List.
Here is a minimal example of how to read the file – which I assume contains only numbers separated by whitespace – and calculate the total. Of-course you need to replace text file path with the actual path to the text file.
File txtFile = new File("text file path");
try (Scanner scan = new Scanner(txtFile)) {
int total = 0;
while (scan.hasNextInt()) {
total += scan.nextInt();
}
System.out.println("Total: " + total);
}
catch (FileNotFoundException xFileNotFound) {
xFileNotFound.printStackTrace();
}
Note that the above code uses try-with-resources.
i have a text file and i want to read the integers and doubles. I dont know how many values i have to read. The first value in the line is always the integer and the second is always the double. I want to save the value of the first line seperately.
200
11010 0.004
500 0.02
637 0.018
How to create 2 arrays and save the values, so i can use them later? I am not allowed to create a new class. I tried to use Point but cant store doubles.
Scanner scanner = new Scanner(new File(args[0]));
int cores= scanner.nextInt();
System.out.print(cores);
while (scanner.hasNext()) {
int x = scanner.nextInt();
double y = scanner.nextDouble();
System.out.printf("x");}
I' ve tried the code above but throws out Exception
You can use simple file handling approach to read the file line by line, For the first line you can use a flag to mark the line and sent the file to remote location you want to save the data. Then for all later lines you can split the string on the basis of " " (space). Post which once you have stripped the elements of the resulting array you can typecast and append the element at first index to integer array. And the second element (typecast before append) to the double array. This shall work absolutely fine with any length of file.
A demo code for the same is as following:
public class ReadLineByLine
{
public static void main(String args[])
{
try
{
FileInputStream fis=new FileInputStream("Demo.txt");
Scanner sc=new Scanner(fis);
String tempLineData = "";
int flag = 0;
String[] elements;
List<Integer> ints = new ArrayList<Integer>(
List<Float> floats = new ArrayList<Float>(
while(sc.hasNextLine())
{
if(flag == 0){
// Place the operation with the first line here
flag++;
}
tempLineData=sc.nextLine();
elements = tempLineData.split(" ");
ints.add((int)elements[0].trim());
floats.add((float)elements[1].trim());
}
sc.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Basically I am asking for the filename with a method called CS160Input (provided by my instructor) to ask for the filename. The text document has a bunch of entries each on their own lines, and I am trying to assign each number to a place in an array, but I am failing to actually write to the array. I know it is finding the file, because when i print out the counter, it tells me the correct amount of lines in the file. But when I try to print out a place in the array, I tried index 3 as you can see in my code, and it gives me 0 regardless of what I try. I tried creating an array of strings first and I ended up getting null for each index value as well.
public static void caclulate() throws FileNotFoundException {
String fileName = CS160Input.readString("Please enter the name of the file: ");
Scanner sc = new Scanner (new File (fileName));
int value, counter = 0;
int array[] = null;
while (sc.hasNextLine()) {
sc.nextLine();
counter++;
}
Scanner scanner = new Scanner(new File(fileName));
int[] calcArray = new int [counter];
int i = 0;
while(scanner.hasNextInt()){
calcArray[i++] = scanner.nextInt();
}
System.out.println(calcArray[3]);
System.out.println(counter);
}
Thanks to #Gendarme pointing out that hasNextInt() could be spitting out false if there were values in between, it made me take a closer look and I realized that in a previous program the numbers being written to the text file were doubles with 2 decimal places. Once I changed to hasNextDouble(), the program worked as intended.
In my class we're using methods to calculate data from a text file. If I had a file that looked exactly like this:
Bob
25
Molly
30
Dylan
10
Mike
65
Is there anyway to pull this data from a file and then send it to a method to calculate, and then return that calculation to display on main? I'm confused as to how Java would be able to skip each line and calculate the numbers instead of the persons name. I was thinking about using inputFile.nextDouble(); and inputFile.nextLine();. But how would I be able to set a String read the lines in the text file if I'm supposed to readthose text file lines variables as doubles? Sorry for all of the questions, I've been stuck on this for a long time and it's driving me crazy >.
You should just alternately use nextLine() and nextInt()
Scanner sc=new Scanner(new File(/* Path to the file*/));
int i=0;
while(sc.hasNext())
{
if(i==0)
{
name=sc.nextLine();
}
else
{
number=sc.nextInt();
}
i=1-i;
}
I recommend you to use an ArrayList to read the full file:
Scanner s = new Scanner(new File(//Here the path of your file));
int number;
String name;
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext())
{
list.add(s.nextLine());
}
Now you have all the lines of your file (as a String) so now you can operate with the full data that it's inside.
Further, the numbers are in the even lines so you can use a loop to through all the lines and check if the line that you are using now it's even or not.
for(int i = 0; i < list.size(); i++)
{
if(i%2 == 0)
{
number = Integer.parseInt(list.get(i));
//You can use the references to your methods with this number
}
else
{
name = list.get(i);
}
}
With the % you will get the rest of the division (I'm using a property of pairs numbers). With Integer.parseInt you will parse your String to int.
So now you will be able to use this numbers to operate or whatever you want.
EDIT: Here you have an example without using ArrayList. In this case I'm going to use nextLine() and nextInt() functions:
Scanner s = new Scanner(new File(//Here the path of your file));
int count = 0;
int number;
int name;
while(s.hasNext())
{
if(i%2 == 0)
{
number = s.nextInt();
s.nextLine();
//You can use the references to your methods with this number
}
else
{
name = s.nextLine();
}
count = count + 1;
}
If you have doubts about why I'm using s.nextLine() after number without storing any value you can look my answer to this question: Why isn't the scanner input working?
I expect it will be helpful for you!
This question already has an answer here:
java.lang.IllegalStateException: Scanner closed
(1 answer)
Closed 4 years ago.
So I have this code and it's supposed to read data from a file called "Numbers.txt". In this file, it is simply just 2003 lines of decimal numbers. The goal of the program is to read this file and make calculations. First I had to get the mean, which I've managed to do, but the problem is I have to now go back in and get the standard deviation. It compiles fine but I get a run error as below:
Exception in thread "main" java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Scanner.java:1115)
at java.util.Scanner.hasNext(Scanner.java:1379)
at StatsDemo.main(StatsDemo.java:49)
This is my code:
File rf2 = new File("Numbers.txt"); //reconnect to the FileReader object passing it the filename
Scanner inputFile2 = new Scanner(rf2);//reconnect to the BufferedReader object passing it the FileReader object.
sum = 0; //reinitialize the sum of the numbers
count = 0; //reinitialize the number of numbers added
//priming read to read the first line of the file
while (inputFile.hasNext()) //loop that continues until you are at the end of the file
{
difference = inputFile.nextDouble() - mean; //convert the line into a double value and subtract the mean
sum += Math.pow(difference,2); //add the square of the difference to the sum
count++; //increment the counter
if (inputFile.hasNextDouble())
inputFile.nextLine(); //read a new line from the file
}
inputFile.close(); //close the input file
stdDev = Math.sqrt(sum/count); //store the calculated standard deviation
I'm not sure why I'm getting this error. I got a similar (but not the same) one from the mean calculation earlier, but the resolve for that doesn't work for this. Any ideas?
After changing to inputFile2...
Exception in thread "main" java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Scanner.java:1115)
at java.util.Scanner.next(Scanner.java:1510)
at java.util.Scanner.nextDouble(Scanner.java:2456)
at StatsDemo.main(StatsDemo.java:51)
Replace inputFile with inputFile2 because it's the Scanner object.
Your Scanner is called inputFile2 not inputFile.
Rename inputFile to inputFile2 in code while (inputFile.hasNext())
Your Scanner object is with inputFile2 and you are using inputFile as a scanner object. I am surprised how is your code running without any compile errors. In case you have another file which is associated with inputFile Scanner object for which you have not provided code above, just check the file and closing of that reference where you are flushing the inputFile object. Otherwise, correct your code as below:
File rf2 = new File("Numbers.txt"); //reconnect to the FileReader object passing it the filename
Scanner inputFile2 = new Scanner(rf2);//reconnect to the BufferedReader object passing it the FileReader object.
sum = 0; //reinitialize the sum of the numbers
count = 0; //reinitialize the number of numbers added
//priming read to read the first line of the file
while (inputFile2.hasNext()) //loop that continues until you are at the end of the file
{
difference = inputFile2.nextDouble() - mean; //convert the line into a double value and subtract the mean
sum += Math.pow(difference,2); //add the square of the difference to the sum
count++; //increment the counter
if (inputFile2.hasNextDouble())
inputFile2.nextLine(); //read a new line from the file
}
inputFile2.close(); //close the input file
stdDev = Math.sqrt(sum/count); //store the calculated standard deviation