BufferReader to write new file with previous info - java

This is the basis of my code. It prints students grades on the console, but how do I use a Buffereader to put all the students grade on a new file.
import java.io.*;
import java.util.InputMismatchException;
import java.lang.*;
import java.util.*;
public class WorkSpace {
private Scanner x;
public void openFile(){
try{
x = new Scanner (new File ("grades.txt"));
}
catch(Exception e){
System.out.println("could not find file");
}}
public void createFile()throws IOException {
try{
File file = new File("grades.txt");
Scanner s = new Scanner(file);
while(s.hasNext()){
{
String [] split = s.nextLine().split(", ");
String fname = split[0];
Double q1 = Double.parseDouble (split[1]);
Double q2 = Double.parseDouble (split[2]);
Double q3 = Double.parseDouble (split[3]);
Double q4 = Double.parseDouble (split[4]);
Double proji = Double.parseDouble (split[5]);
Double projii = Double.parseDouble (split[6]);
Double projiii = Double.parseDouble (split[7]);
double studentgrade = (q1 *0.1) + (q2 *0.1) +(q3 *0.1) + (q4 *0.1) +(proji*0.15) + (projii * 0.2) + (projiii *0.25);
if(studentgrade>90)
System.out.printf("%s got an A\n", fname);
else if(studentgrade>80)
System.out.printf("%s got a B\n", fname);
else if(studentgrade>70)
System.out.printf("%s got a C\n", fname);
else if(studentgrade>60)
System.out.printf("%s got a D\n", fname);
else if(studentgrade>50)
System.out.printf("%s got a F\n", fname);
}}}catch(Exception e){
e.printStackTrace();
}
}
public void closeFile(){
x.close();
}

Scanner.nextInt() returns next integer value read from source (not source length or something). You open the file and try to read integer in the beginning, but the file doesn't start with integer so you get an exception.

How you are reading your file is incorrect. The most common way to read files with scanner:
try{
File file = new File("Your/File/Path");
Scanner s = new Scanner(file);
s.useDelimiter("\n");//splits the whole file's text by "\n"
while(s.hasNext()){
String next = s.next();
//parse your stuff
}
s.close();
}catch(Exception e){}
Also, scanner.nextInt() doesn't return the file's length. That was the problem. Use file.length to get the file's length.

Your question doesn't make sense. BufferedReader doesn't write files. It, err, reads files. What you want is, err, a BufferedWriter.

Related

I need help reading a text file to print to the console

I having trouble figuring this out it supposed to print the contents of the txt file but i cant get it print.
This is the output im supposed to get.
Ingredient __________Amount Needed ______ Amount In Stock
baking soda_________4.50 ________________4.00
sugar ______________6.50________________3.20
import java.util.Scanner;
import java.lang.*;
import java.io.FileReader;
import java.io.IOException;
import java.io.*;
public class Lab8b {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter file name : ");
String filename = scan.nextLine();
Scanner fileScan = new Scanner(new File(filename));
while (fileScan.hasNext()) {
String name = fileScan.nextLine();
String ingredientName = fileScan.nextLine();
double amountNeeded = Double.parseDouble(fileScan.nextLine());
double amountInStock = Double.parseDouble(fileScan.nextLine());
if (amountNeeded > amountInStock) {
System.out.printf("Ingredient \t Amount Needed \t Amount in Stock");
System.out.println();
System.out.printf("%10s", ingredientName);
System.out.printf("%8.2f", amountNeeded);
System.out.printf("%16.2f", amountInStock);
} //end if
if (amountNeeded <= amountInStock) {
System.out.println("Nothing");
} //end while
} //end if
} //end main
} //end class
Here are the problems I found with your code:
You created a while loop to read the contents of the file, but you don't do anything with it.
Need to wrap the code in a try-catch since FileNotFoundException might be thrown.
You attempt to call readLine() from filename instead of fileScan
I've assumed that you need amountNeeded and amountInStock to be doubles even though you don't do any calculations with them. If this isn't the case, you can simply leave them as strings instead of parsing.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter file name : ");
String filename = scan.nextLine();
scan.close();
Scanner fileScan = null;
try {
fileScan = new Scanner(new File(filename));
while (fileScan.hasNext()) {
String ingredientName = fileScan.nextLine();
double amountNeeded = Double.parseDouble(fileScan.nextLine());
double amountInStock = Double.parseDouble(fileScan.nextLine());
System.out.printf("Ingredient \t Amount Needed \t Amount in Stock\n");
System.out.printf("%10s", ingredientName);
System.out.printf("%8.2f", amountNeeded);
System.out.printf("%16.2f", amountInStock);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

How do i put a Try-catch statement looking for a file in a loop?

I need to put my searching of the file in my readData() method in a loop that catches the fine not found exception then loops to prompt the user again for the file name until the correct one is entered. Once the proper file name is entered, then the return values pass to the other methods to continue the code.
I have tried putting the block of code into a do-while method but it results in a infinite loop. I need assistance with the semantics of this.
private static ArrayList<Double> readData() {
ArrayList<Double> inputValues = new ArrayList<>();
String inputFileName;
double value;
Scanner input = new Scanner(System.in);
System.out.print("Enter the name of the input file: ");
inputFileName = input.nextLine();
File file = new File(inputFileName);
do{
try {
input = new Scanner(file);
while (input.hasNextDouble()) {
value = input.nextDouble();
inputValues.add(value);
}
}
catch (FileNotFoundException e) {
System.out.println("File not found!");
System.out.println("Please enter file name again: ");
}
}
while(!file.exists());
return inputValues;
}
I am expecting this to explain "File not found!" then prompt again for the file name until the correct one is entered. However it only does the try-catch once and then attempts to return the inputValues return value. This causes the program to crash.
I have tried do while loop. But it ends up in an infinite loop
package weightedavgdataanalyzer;
import java.io.*;
import java.util.*;
public class WeightedAvgDataAnalyzer {
public static void main(String[] args) {
ArrayList<Double> inputValues = readData();
double weightedAvg = calcWeightedAvg(inputValues);
printResults(inputValues, weightedAvg);
}
private static void printResults(ArrayList<Double> inputValues, double weightedAvg) {
System.out.print("Enter output file name: ");
Scanner input = new Scanner(System.in);
String outputFile = input.nextLine();
try {
PrintWriter writer = new PrintWriter(outputFile);
writer.print("The weighted average of the numbers is " + weightedAvg + ", when using the data ");
for (int i = 2; i < inputValues.size(); i++) {
writer.print(inputValues.get(i) + ", ");
}
writer.println("where " + inputValues.get(0)
+ " is the weight used, and the average is computed after dropping the lowest "
+ Integer.valueOf((int) inputValues.get(1).doubleValue()) + " values.");
writer.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static double calcWeightedAvg(ArrayList<Double> inputValues) {
double sum = 0;
double average;
double weight = inputValues.get(0);
int toDrop = Integer.valueOf((int) inputValues.get(1).doubleValue());
ArrayList<Double> newList = new ArrayList<>();
for (int i = 2; i < inputValues.size(); i++) {
newList.add(inputValues.get(i));
}
Collections.sort(newList);
for (int i = (toDrop); i < newList.size(); i++) {
sum += weight * newList.get(i);
}
average = sum / (newList.size() - toDrop);
return average;
}
private static ArrayList<Double> readData() {
ArrayList<Double> inputValues = new ArrayList<>();
String inputFileName;
double value;
Scanner input = new Scanner(System.in);
System.out.print("Enter the name of the input file: ");
inputFileName = input.nextLine();
File file = new File(inputFileName);
do{
try {
input = new Scanner(file);
while (input.hasNextDouble()) {
value = input.nextDouble();
inputValues.add(value);
}
}
catch (FileNotFoundException e) {
System.out.println("File not found!");
System.out.println("Please enter file name again: ");
}
}
while(!file.exists());
return inputValues;
}
}
Move the initialization of File file = new File(inputFileName); inside the loop as well as the "ask for new file name line". And last step is to also check if the file is an directory. You can't read directories with a Scanner, but file.exists() will still return true
private static ArrayList<Double> readData() {
ArrayList<Double> inputValues = new ArrayList<>();
String inputFileName;
double value;
Scanner input = new Scanner(System.in);
File file;
System.out.print("Enter the name of the input file: ");
do {
inputFileName = input.nextLine();
file = new File(inputFileName);
try {
input = new Scanner(file);
while (input.hasNextDouble()) {
value = input.nextDouble();
inputValues.add(value);
}
} catch (FileNotFoundException e) {
System.out.println("File not found!");
System.out.println("Please enter file name again: ");
}
} while (!file.exists() && !file.isDirectory());
return inputValues;
}
The other answers have not addressed that it is bad practice to control the flow of your code using catch and exception. You should reserve using your catch block for typically printing your errors or logging them.
I moved the logic of asking for the file into a loop that does not depend on an exception to correctly execute and placed it into a reusable method.
Here is what this change would look like:
ArrayList<Double> inputValues = new ArrayList<>();
double value;
File file = promptForFile(); //Condensed into a clean reusable single line of code
try {
Scanner input = new Scanner(file);
while (input.hasNextDouble()) {
value = input.nextDouble();
inputValues.add(value);
}
} catch (FileNotFoundException e) {
e.printStackTrace(); //Or log the error
}
And the method you can reuse anywhere for a new prompt:
public static File promptForFile()
{
System.out.print("Enter the name of the input file: ");
Scanner input = new Scanner(System.in);
String inputFileName = input.nextLine();
File file = new File(inputFileName);
while(!file.exists() && !file.isDirectory())
{
System.out.println("File not found!");
System.out.println("Please enter file name again: ");
inputFileName = input.nextLine();
file = new File(inputFileName);
}
return file;
}
Now the logic of your code is separated from searching for the file and the code is extremely reusable and readable.
This couldn't be done before since you had two different logics mixed intertwined.
File myFile = new File("myFile.txt");
while(!myFile.exists()){
//re-enter filename and instantiate myFile as a new object using it as the argument
}
could just check whether the file exists in a loop like so before using it. The issue with looping for the FileNotFoundException is that your writer is what throws that, so you would have to constantly instantiate the writer and check whether the exception is thrown before possibly looping again, which isn't ideal.
The problem is when the exception is caught, you never ask for a new file name, so you are running the code on the same faulty file path over and over again. To fix this, just move this code block:
System.out.print("Enter the name of the input file: ");
inputFileName = input.nextLine();
File file = new File(inputFileName);
inside the loop.
You may also want to eliminate a condition on your loop, and instead add a return; at the end of your try block.
private static ArrayList<Double> readData() {
ArrayList<Double> inputValues = new ArrayList<>();
String inputFileName;
double value;
Scanner input = new Scanner(System.in);
while (true) {
try {
// Get response in the loop, instead of one time-only
System.out.print("Enter the name of the input file: ");
inputFileName = input.nextLine();
File file = new File(inputFileName);
input = new Scanner(file);
while (input.hasNextDouble()) {
value = input.nextDouble();
inputValues.add(value);
}
// Add your return statement here to get rid of the conditional
// loop.
return inputValues;
}
catch (FileNotFoundException e) {
System.out.println("File not found!");
System.out.println("Please enter file name again: ");
}
}
}
You can take input and can return once file is found or else can keep recording error message
public File getFile(){
while(true) {
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("Enter the name of the input file: ");
File file = new File(System.in);
if (file.exists()) {
return file;
}else{
System.out.println("File not found! Please try again ");
}
}
}
}
private List<Double> getData(File file){
List<Double> listOfDoubles = new ArrayList<>();
try(Scanner scanner = new Scanner(file)){
while(scanner.hasNextDouble()) {
listOfDoubles.add(scanner.nextDouble());
}
}
return listOfDoubles;
}
private static ArrayList<Double> readData() {
ArrayList<Double> inputValues = new ArrayList<>();
File inputFile = getFile();
return getData(inputFile);
}

java keep trying until there are no more filenotfoundexception

I was trying to write code which would read an input file and create an output file. But when I tried to add a try until a correct input file name is input, I had problems. It shows not proper filenotfound exception is in try....
public static void main(String[] args) throws FileNotFoundException
{
//prompt for the input file name
Scanner in = new Scanner(System.in);
//keep trying until there are no more exceptions
//boolean done = false;
String inputfilename = " ";
while (!done)
{
try
{
System.out.print("Input file name (from your computer): ");
inputfilename = in.next();
done = true;
}
catch (FileNotFoundException exception)
{
System.out.println("****** ERROR ******\nCannot locate the input file '" + inputfilename + "' on your computer - please try again.");
}
}
//prompt for the output file name
System.out.print("What would you like to call your output file: ");
//use outputfilename variable to hold input value;
String outputfilename = in.next();
//construct the Scanner and PrintWriter objects for reading and writing
File inputfile = new File(inputfilename);
Scanner infile = new Scanner(inputfile);
PrintWriter out = new PrintWriter(outputfilename);
//read the input and write the output
out.println("Here is the class average for mstu4031:\n");
double totalgrade = 0;
double number = 0;
while (infile.hasNextDouble())
{
double grade = infile.nextDouble();
out.println("\n");
out.printf("%.1f\n",grade);
number++;
totalgrade = totalgrade + grade;
}
//print numbers and average in output file
out.println("\n\n");
out.printf("\nNumber of grades: %.1f",number);
//calculate average
double average = totalgrade/number;
out.println("\n\n");
out.printf("\nAverage: %.2f",average);
finally
{
in.close();
out.close();
}
}
There is no method in your try block that may throw a FileNotFoundException.
Try to instantiate your Scanner in the try block. It will throw the expected FileNotFoundException if the filename read from stdin does not exist:
String inputfilename = null;
Scanner infile = null;
while (!done)
{
try
{
System.out.print("Input file name (from your computer): ");
inputfilename = in.next();
infile = new Scanner(new File(inputfilename));
done = true;
}
catch (FileNotFoundException exception)
{
System.out.println("****** ERROR ******\nCannot locate the input file '" + inputfilename + "' on your computer - please try again.");
}
}
Wrong here. You are only receiving input without checking if the file actually exist. Every valid inputs will let you get out of the loop.
if(new File(inputfilename).exist()){
done = true;
}else{
System.out.println("****** ERROR ******\nCannot locate the input file '" + inputfilename + "' on your computer - please try again.");
}
You can only catch an exception if something in the try block may throw an exception.
However, you should test for existence of a file with File.exists(), instead of catching an exception.
File file;
do {
System.out.print("Input file name (from your computer): ");
file = new File(in.next());
} while (!file.exists());
Opening a file may throw an Exception. That's Why you need to put them inside try block. You have put only reading the input part inside try-catch block
Hope this code works properly:
//prompt for the input file name
Scanner in = new Scanner(System.in);
//keep trying until there are no more exceptions
//boolean done = false;
String inputfilename = " ";
while (!done)
{
try
{
System.out.print("Input file name (from your computer): ");
inputfilename = in.next();
done = true;
//prompt for the output file name
System.out.print("What would you like to call your output file: ");
//use outputfilename variable to hold input value;
String outputfilename = in.next();
//construct the Scanner and PrintWriter objects for reading and writing
File inputfile = new File(inputfilename);
Scanner infile = new Scanner(inputfile);
PrintWriter out = new PrintWriter(outputfilename);
//read the input and write the output
out.println("Here is the class average for mstu4031:\n");
double totalgrade = 0;
double number = 0;
while (infile.hasNextDouble())
{
double grade = infile.nextDouble();
out.println("\n");
out.printf("%.1f\n",grade);
number++;
totalgrade = totalgrade + grade;
}
//print numbers and average in output file
out.println("\n\n");
out.printf("\nNumber of grades: %.1f",number);
//calculate average
double average = totalgrade/number;
out.println("\n\n");
out.printf("\nAverage: %.2f",average);
}
catch (FileNotFoundException exception)
{
System.out.println("****** ERROR ******\nCannot locate the input file '" + inputfilename + "' on your computer - please try again.");
}
}
finally
{
in.close();
out.close();
}

NumberFormatException with File IO

I keep getting a NumberFormatException, which I understand arises due to a string conversion. I am converting st.nexttoken to a double with Double.parseDouble.
Any help would be much appreciated!
import java.io.*;
import java.util.*;
public class FileIO {
public static void main(String[] args) throws Exception {
double sum = 0, next ;
int ctr = 0;
String line;
String filename = "numbers.txt";
StringTokenizer st;
PrintWriter outFile = new PrintWriter("output.txt");
outFile.println("Output File");
try{
Scanner inFile = new Scanner(new FileReader (filename));
while (inFile.hasNext())
{
line = inFile.nextLine();
st = new StringTokenizer(line);
while (st.hasMoreTokens()){
next = Double.parseDouble(st.nextToken());
sum += next;
ctr++;
System.out.println(next);
outFile.println(next);
}
}
System.out.println("number of doubles read is " + ctr);
System.out.println("average is " + sum/(double)ctr);
outFile.println("number of doubles read is " + ctr);
outFile.println("average is " + sum/(double)ctr);
outFile.close();
}
catch(FileNotFoundException e){
System.out.println("The file numbers.txt was not found");
}
catch(NumberFormatException e){
System.out.println("sorry - number format error");
System.out.println(e);
}
}
}
The error from NetBeans reads sorry - number format error
java.lang.NumberFormatException: For input string: "Output"
numbers.txt has some integers as well as doubles with decimal points.
output.txt is blank, but saved in the same file path as numbers.txt
Here is the body of numbers.txt as requested.
13 12 15 3
74.4 67.3 43.8 77.7 233.4 678.9
public static void main(String[] args) throws Exception {
double sum = 0, next ;
int ctr = 0;
String line;
String filename = "numbers.txt";
StringTokenizer st;
PrintWriter outFile = new PrintWriter("output.txt");
outFile.println("Output File");
try{
Scanner inFile = new Scanner(new FileReader(filename));
while (inFile.hasNext())
{
line = inFile.nextLine();
st = new StringTokenizer(line);
while (st.hasMoreTokens()){
next = Double.parseDouble(st.nextToken());
sum += next;
ctr++;
System.out.println(next);
outFile.println(next);
}
}
System.out.println("number of doubles read is " + ctr);
System.out.println("average is " + sum/(double)ctr);
outFile.println("number of doubles read is " + ctr);
outFile.println("average is " + sum/(double)ctr);
outFile.flush();
inFile.close();
outFile.close();
}
catch(FileNotFoundException e){
System.out.println("The file numbers.txt was not found");
}
catch(NumberFormatException e){
System.out.println("sorry - number format error");
System.out.println(e);
}
}
Above is modified version of your code and it works fine with the below given number.txt.
You need use the flush() write it to the final destination.
Here is the number.txt
12 12.0 12
12 32 56
34
34.0

Why won't the BufferedWriter instantiation write to a txt file in Java?

I am trying to instantiate a object with BufferedWriter and it wont work. The problem happens when I use the write function. Why won't it let me write to the file?
The error is cannot find symbol. Please help me. I know someone knows. Why wont it not find the symbol when this is a bufferedWriter method?
package ex5_abcd;
import java.nio.file.*;
import java.io.*;
import static java.nio.file.StandardOpenOption.*;
import java.util.Scanner;
public class EX5_ABCD {
public static void main(String[] args) {
boolean go = true;
String firstN, lastN;
String lineWritten = "";
int IdNum;
Scanner input = new Scanner(System.in);
Path file = Paths.get("C:\\Java\\empList.txt");
try {
OutputStream output = new BufferedOutputStream(Files.newOutputStream(file, CREATE));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
while (go) {
System.out.println("Please enter Employee's First Name");
firstN = input.nextLine();
System.out.println("Please enter Employee's Last Name");
lastN = input.nextLine();
System.out.println("Please enter " + firstN + " " + lastN);
IdNum = input.nextInt();
lineWritten = IdNum + " " + firstN + " " + lastN;
int lineLength = lineWritten.length();
char [] testChar = new char[1];
testChar [0] = 'a';
writer = write(testChar, 0, lineLength); // Why write error
writer.flush();
writer.newLine();
}
writer.close();
} catch (Exception e) {
System.out.println("Error Msg:" + e);
}
}
}
writer = write(lineWritten, 0, lineLength);
should be rewritten to
writer.write(lineWritten, 0, lineLength);
since writer is not a reference to an object, you should call the method of the writer object, not set writer to another value
Recap:
(=) sets a value.
Also, since you never set the value of go as false in your loop, you will keep on looping there... forever... and ever.... I suggest to not let that happen

Categories