Java File Problems - java

So we want an application to allow the user to enter the names and grades of students the user should be prompted for the name of the file to create and for the number of students to be entered (1 grade per student). Then the program takes all of the grades and averages them. The problem is that it is not reading the file and always gives us a average of -0.0.
`
public static void main(String[] args) throws IOException {
System.out.println("What is the name of the file you would like to create?");
filename = p.next();
File fd = new File(filename + ".txt");
fd.createNewFile();
students(fd);
}
public static void students(File fd) throws IOException {
int numbstudents;
FileWriter ap = new FileWriter(fd, true);
BufferedWriter ad = new BufferedWriter(ap);
System.out.println("How many students would you like to add?");
numbstudents = p.nextInt();
int i = 0;
while (i != numbstudents) {
for (i = 0; i < numbstudents; i++) {
System.out.println("What is the name of student number " + i + " ?");
String name = p.next();
ad.write(name);
ad.newLine();
System.out.println("What grade did student number " + i + " acheive?");
String a = f.next();
ad.write(a);
ad.newLine();
}
}
read(fd);
ad.close();
}
public static void read(File fd) throws FileNotFoundException {
int counter = 0;
FileReader h;
BufferedReader g;
String test;
double average, total = 0;
int number = 0;
int i = 0;
try {
h = new FileReader(fd);
g = new BufferedReader(h);
while ((test = g.readLine()) != null) {
number += 1;
System.out.println(test);
counter = counter + 1;
i = counter % 2;
if (i == 0) {
total += Double.parseDouble(test);
}
}
average = total / (number - 1);
System.out.println("The students average is: " + average);
g.close();
fd.delete();
} catch (FileNotFoundException e) {
System.out.println("File could not be found.");
} catch (IOException e) {
System.out.println("Your file could not be read.");
}
}
}
`

You're attempting to read from the file before you've closed the writer.
The close() call includes flushing buffered data to disk. You're reading before data is flushed to disk.
As a side note, consider what you're accomplishing with this pair of statements:
while (i != numbstudents) {
for (i = 0; i < numbstudents; i++) {
The while is unnecessary. The for statement iterates over the comfortably numb students.
Also note the difference in conditions between the two. In general, when iterating over numbers, it's safer to use '<', '<=', '>' or '>=' than '==' or '!='. Otherwise, if you pass by the endpoint before an equality condition, it will continue happily past the end.
Finally, consider naming your methods with descriptive verb phrases. This will help you with breaking the big problem down into smaller pieces. For example, you could have one method called inputStudents() that reads input and creates and closes the file, called before another method printAverageOfStudents() that reads the file and computes the average.

Related

Incorrect output in Java program

This is the description of the problem and here is the code that I got:
PP 10.1 Design and implement a program that reads a series of 10 inte- gers from
the user and prints their average. Read each input value as a string, and then
attempt to convert it to an integer using the Integer.parseInt method. If this process
throws a NumberFormatException (meaning that the input is not a valid number),
print an appropriate error message and prompt for the number again. Continue
reading values until 10 valid integers have been entered.
This is the code I have so far:
import java.util.Scanner;
public class average
{
private int number_values;
private int[] int_values;
private double average;
public average(int number_values)
{
this.number_values = number_values;
}
public void values()
{
String value_string = null;
int int_value = 0,a;
Scanner number = null;
a = 0;
int_values = new int [number_values];
while (a < number_values)
{
try{
number = new Scanner(System.in);
System.out.print("Please enter a value:");
value_string = number.nextLine();
int_value = Integer.parseInt(value_string);
int_values[a++] = int_value;
}
catch (NumberFormatException ex)
{
System.out.print("This is an invalid input. Please renter another number:");
continue;
}
}
}
public void printValues()
{
System.out.println("The values are:");
for (int a = 0; a < number_values; a++)
{
System.out.println("Number - " + (a + 1) + " = " + int_values);
}
}
public double get_average()
{
int sum = 0;
for(int a = 0; a < number_values; a++)
{
sum += int_values[a];
}
average = (double) sum / number_values;
return (average);
}
public static void main(String[] args)
{
average a = new average(10);
a.values();
a.printValues();
System.out.println("Average = " + a.get_average());
}
}
When I enter an incorrect character it says "This is an invalid input. Please renter another number:Please enter a value:"
And when I displays the average it says Number - 1 = [I#330bedb4" for all of the values.
So the println string when I enter a incorrect input is messed up and the values are messed up. What am I missing?
Try intValues[i], if you want to output a specific item of your array. Otherwise you get the toString representation of the array object itself.
And please next time post your code instread of screenshots ;)
You're not printing the elements of the array. You're printing the array string representation directly. The error is done in your printValues() method.
To solve this, you must call an element of the array. In this case, you want to call all elements, so you must use a loop. Here:
public void printValues()
{
System.out.println("The values are:");
for (int a = 0; a < number_values; a++)
{
System.out.println("Number - " + (a + 1) + " = " + int_values[i]);
}
}

Having trouble scanning an Int

I'm new to Java, and struggling with something I've never had trouble with in the past. For whatever reason, I can't scan an int (or a double) in my code, but I can scan a string just fine. I'm posting the snippet where my scanner isn't functioning, please let me know if I should include the rest of the program.
import java.util.Scanner;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
public class DZP3
{
public static void main(String[] args) throws IOException
{
announce();
Scanner scan = new Scanner(System.in);
//Prompt user for input file
System.out.println("Greetings! Please enter the filename of the plaintext olympics data file you'd like to open.");
String txtFilename = scan.nextLine();
//Opens olympics data txt file specified, exits if it does not exist
File medalsInput = new File (txtFilename);
if(!medalsInput.exists())
{
System.out.println("File not found. Reload and try again.");
System.exit(1);
}
//Prompt user for output file
System.out.println("Thanks. Please enter the filename of the plaintext data output file.");
String outputTxt = scan.nextLine();
//Create output file specified
File medalsOutput = new File (outputTxt);
//Prompt user for medal cutoff X value
System.out.println("Thanks. Please enter the minimum number of medals a nation must have earned to be counted for calculation 2 listed above. \nEnter the value, as an integer:");
int medalsCutoff = 0;
medalsCutoff = scan.nextInt();
fileProcessing(medalsInput, medalsOutput, medalsCutoff);
}
}
Near the bottom, medalsCutoff is not accepting any scanned value whatsoever. I've tried putting it in a method other than main, I've tried rearranging it, creating a separate scanner just for it, and a few other things. The debugger shows that, no matter what, I'm stuck on that line of code. What have I done wrong? I'm at a loss.
EDIT: Here's the fileProcessing method, and what comes after. The announce method is just system.out.println.
public static void fileProcessing(File medalsIn, File medalsOut, int medalsMin) throws IOException
{
//Initialize necessary variables and strings
int maxTotMedals = -1;
int natCountMedalsMin = 0;
int natHiScore = -1;
String natName;
String answerOne = "DEFAULT";
int answerTwo = 0;
String answerFour = "DEFAULT";
//Create Printwriter
PrintWriter pw = new PrintWriter(medalsOut);
//Create scanner to read from file, loop until end of file
Scanner filescan = new Scanner(medalsIn);
while (filescan.hasNext())
{
//Initializes medal counting variables at zero, resetting the values with each line
int gCount = 0;
int sCount = 0;
int bCount = 0;
natName = filescan.next();
int lineMedals = 0;
while (lineMedals < 4); //Runs 4 times to cover all four years
{
gCount += filescan.nextInt();
sCount += filescan.nextInt();
bCount += filescan.nextInt();
lineMedals++;
}
int totalMedals = gCount + sCount + bCount;
//Sees if this line's medals have exceeded previous total medal record, if yes, sets country name as answer to question one
if (totalMedals > maxTotMedals)
{
answerOne = natName;
maxTotMedals = totalMedals;
}
if (totalMedals >= medalsMin)
{
natCountMedalsMin++; //For answer two
}
//Score calculation
int natScore = gCount*3;
natScore += sCount*2;
natScore += bCount;
//Compares score to highest score, for answer four
if (natScore > natHiScore)
{
answerFour = natName;
natHiScore = natScore;
}
//Write nation name and score to file
pw.println(natName + " " + natScore);
}
//Define answer two after all countries have been counted
answerTwo = natCountMedalsMin;
//Close output file
pw.close();
//Send results to answer method
answerPrint(answerOne, answerTwo, answerFour, medalsMin, natHiScore);
}
//This method outputs the answers to the user.
public static void answerPrint(String answerEin, int answerZwei, String answerVier, int medalsMini, int HiScore)
{
System.out.println("File read successfully.");
System.out.println("The nation that earned the greatest number of medals is " + answerEin + ".");
System.out.println(answerZwei + " countries earned more than " + medalsMini + " medals.");
System.out.println("The nation with the highest score is " + answerVier + " with a score of " + HiScore + ".");
System.out.println("Thank you for using this program. Until next time!");
}
EDIT 2: This has been solved, I had a stray semicolon in my fileProcessing method that caused an infinite loop. Thank you all for your help.
while (lineMedals < 4);
Above line has a semicolon at the end. It is an infinite loop.
after file creation ,you use this below method
File medalsOutput = new File (outputTxt);
medalsOutput.createNewFile()
in ur code file not got created and exiting via syste.exit(1)

OutOfBoundsException When Calling Return For A Method JAVA

i'll get straight to the chase. If a user wants to read another file they must type r in the menu, then they are thrown with a return readFile(); method which takes them to the top of the program and asks them the same question it did at the beggining when they first ran this program. Only issue is when you type R or Default it throws an OutOFBoundsException. BTW It is Reading a CSV file
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1000
at studentrecs.StudentRecs.in(StudentRecs.java:71)
at studentrecs.StudentRecs.readFile(StudentRecs.java:55)
at studentrecs.StudentRecs.menu(StudentRecs.java:97)
at studentrecs.StudentRecs.main(StudentRecs.java:33)
Java Result: 1
/
public static Boolean readFile(String filename) throws IOException { //Constructor for filename
try {
Scanner userInput = new Scanner(System.in);
System.out.println("Type R To Read a File or Type Default for the default file");
user = userInput.nextLine();
if (user.equalsIgnoreCase("r")) {
user = userInput.nextLine();
}
filename = user;
if (user.equalsIgnoreCase("default")) {
filename = "newreg2.csv";
}
Scanner input = new Scanner(new FileReader(filename));
while (input.hasNext()) {
in(input.nextLine());
numstu++;
}
input.close();
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
return false;
}
public static void in(String reader) {
String splitter[];
splitter = reader.split(",");
stu[numstu] = new StuRec();
stu[numstu].studentID = splitter[0];
stu[numstu].lastName = splitter[1];
stu[numstu].firstName = splitter[2];
stu[numstu].phoneNumber = splitter[3];
stu[numstu].courseCode = splitter[4];
stu[numstu].periodNumber = Integer.parseInt(splitter[5]); // parseInt turns a string of digits into an integer
stu[numstu].mark = Integer.parseInt(splitter[6]);
}
public static boolean menu() throws IOException {
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
System.out.println("Type X To Exit The Program");
choice = userInput.nextLine();
double average = 0.0; // declare average
if (choice.equalsIgnoreCase("L")) {
for (int i = 0; i < numstu; i++) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}
}else if (choice.equalsIgnoreCase("R")){
return readFile(filename);
} else if (choice.equalsIgnoreCase("AA")) {
for (int i = 0; i < numstu; i++) {
average += stu[i].mark; // keep adding to average
}
}else if (choice.equalsIgnoreCase("X")) {
for (int i = 0; i < numstu; i++) {
System.exit(i);
}
}else if (choice.equalsIgnoreCase("AC")) {
} else {System.err.println("Unknown Key Try Again...");
}
// divide by zero protection
if ( choice.equalsIgnoreCase("AA") && numstu > 0 ) {
average = average/numstu; // compute the average. Always use the size in terms of a variable whenever possible.
System.out.println(average); // as noted below, if this is an integer value, < #of students computations will eval to 0.
}
else if (!choice.equalsIgnoreCase("AA") && numstu < 0) {
System.out.println("Oops! No Marks To Calculate! :(");
}
return menu();
}
}
It looks like EITHER you have initialised numstu to start at 1, OR you have more than 1000 lines in your file.
The effect of either of these errors would be that you eventually attempt to write data to entry 1000 of stu. But since you've initialised stu with 1000 entries, numbered from 0 to 999, this gives your error.
You should make sure that numstu is initially 0, not 1.
And next time you post a question, post ALL of your code, not just the parts where you think the error might be. It's very difficult for most people to find bugs in code that they can't see.

How to find average mark of an array list that comes from a csv file (JAVA) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a csv file that has a list with student id's, lastname, firstname, marks, phone number, etc. I have organized them into an array list so when you call stu[100].mark it will find the mark of the 100th student on the list of the csv file. There are 1000 students. I need to calculate the total overall average mark for all the students (each student only has one mark) I have put it in a loop, but it just prints out their mark. If you need more details, than I apologize.
Here is the code:
public class StudentRecs {
public static String user;
public int StuRec;
public static int numstu;
public static double average;
//public static StuRec[] stu;
static StuRec[] stu = new StuRec[1000];
public static void main(String[] args) throws IOException {
for (int i = 0; i < 1000; i++) {
stu[i] = new StuRec();
}
StuRec stu = new StuRec();
readFile(user);
menu();
}
public static String filename;
Scanner reader = new Scanner(filename);
public static Boolean readFile(String filename) throws IOException { //Constructor for filename
try {
Scanner userInput = new Scanner(System.in);
System.out.println("Type R To Read a File or Type Default for the default file");
user = userInput.nextLine();
if (user.equalsIgnoreCase("r")) {
user = userInput.nextLine();
}
filename = user;
if (user.equalsIgnoreCase("default")) {
filename = "newreg2.csv";
}
Scanner input = new Scanner(new FileReader(filename));
while (input.hasNext()) {
in(input.nextLine());
numstu++;
}
input.close();
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
return false;
}
public static void in(String reader) {
String splitter[];
splitter = reader.split(",");
stu[numstu] = new StuRec();
stu[numstu].studentID = splitter[0];
stu[numstu].lastName = splitter[1];
stu[numstu].firstName = splitter[2];
stu[numstu].phoneNumber = splitter[3];
stu[numstu].courseCode = splitter[4];
stu[numstu].periodNumber = Integer.parseInt(splitter[5]); // parseInt turns a string of digits into an integer
stu[numstu].mark = Integer.parseInt(splitter[6]);
}
public static boolean menu() {
int total = 0;
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
choice = userInput.nextLine();
for (int i = 0; i < numstu; i++) {
if (choice.equalsIgnoreCase("L")) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}else if (choice.equalsIgnoreCase("R")){
} else if (choice.equalsIgnoreCase("AA")) {
total = total + stu[i].mark;
} else {
System.err.println("Unknown Key Try Again...");
}
average = total / 1000; // compute the average.
System.out.println(average);
} return menu();
}
}
Your average routine is computing incorrectly. It's simply taking the n'th mark and adding it to itself, divided by 1000. Since you're using integers, it will just round down, effectively giving you n'th mark + 0 for average on each iteration, leaving you with the last mark on the loop completion.
You need to keep adding to average, and divide by 1000 when you are done to get the value.
public static boolean menu() {
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
choice = userInput.nextLine();
for (int i = 0; i < numstu; i++) {
if (choice.equalsIgnoreCase("L")) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}else if (choice.equalsIgnoreCase("R")){
} else if (choice.equalsIgnoreCase("AA")) {
average += stu[i].mark; // keep adding to average
} else {
System.err.println("Unknown Key Try Again...");
}
}
// divide by zero protection
if ( numstu > 0 ) {
average = average/numstu; // compute the average. Always use the size in terms of a variable whenever possible.
System.out.println(average); // as noted below, if this is an integer value, < #of students computations will eval to 0.
// might be better to use double
}
else {
System.out.println("Oops! No students! :(");
}
return menu();
}
Note that your menu is a little inefficient, but the problem at hand should be solved.
Others have already pointed out the issue with not correctly calculating the sum of the scores, the numerator of the average calculation. I want to focus on the issue of the number of scores, the denominator of the average calculation.
Think real world. As others have mentioned, you cannot depend on the number of students in the file being fixed. File/class size can vary, so you cannot divide by a fixed number.
But neither can you depend on the number of scores being the same as the number of students, so you cannot simply divide by the number of students in that file. A student might not have a mark for a particular assignment (sickness, excused absence, or whatever). A good routine will account for the possibility of blanks (as well as invalid values), and thus I would expect you to need to count the valid, non-blank marks at the same time that you total them so that you can take the appropriate quotient at the end.
This statement is the problem
average = stu[i].mark + stu[i].mark / 1000;
This does not accumulate a total. Instead try
total = total + stu[i].mark;
And then at the end, outside the loop
average = total / 1000;

Displaying Information Within Random Access File

I have created an application that allows the user to enter their account number, balance(no more than 99999), and last name. The program will take this information and insert it into a .txt file at a location corresponding to the account number(acct). Here is the code for that:
import java.io.*;
public class NationalBank {
public static void main(String[] args) throws Exception{
InputStreamReader temp = null;
BufferedReader input = null;
try {
temp = new InputStreamReader(System.in);
input = new BufferedReader(temp);
int acct;
double amount;
String name;
RandomAccessFile file = new RandomAccessFile("bank.txt", "rw");
while(true) {
// Asks for input
System.out.println("Enter Account Number (0-9999): ");
acct = Integer.parseInt(input.readLine());
System.out.println("Enter Last Name: ");
name = input.readLine();
System.out.println("Enter Balance ");
amount = Double.parseDouble(input.readLine());
// Making sure account numbers are between 0 and 9999
if(acct >=0 && acct <= 9999) {
file.seek(acct*17);
file.write(truncateName(name));
file.writeBytes(" " +amount);
}
else {
continue;
}
// Asks user if more entries are needed
System.out.println("Enter More? (y/n)");
if (input.readLine().toLowerCase().equals("n"))
break;
}
file.close();
}
catch (Exception e) {
}
}
// Truncate/adding spaces to name until 8 characters
public static byte[] truncateName (String name) {
byte[] result = new byte[8];
for (int i = 0; i < 8; i++)
result [i] = i < name.length () ? (byte)name.charAt (i) : (byte)' ';
return result;
}
}
Now, I am trying to make an application that will write back all of the accounts that have information within them(with last name and balance). I need to display the account number, balance, and last name of those accounts. So far, I have:
import java.io.*;
public class DisplayBank {
public static void main(String[] args) throws IOException {
FileInputStream input = new FileInputStream ("bank.txt");
try {
byte[] record = new byte[17];
while (input.read(record) == 17) {
String name = new String(record, 0, 8);
long bits = 0;
for (int i = 8; i < 17; i++) {
bits <<= 8;
bits |= record[i] & 0xFF;
}
double amount = Double.longBitsToDouble(bits);
System.out.println("Account Number: " + record + " Name: " + name + ", amount: " + amount);
}
}
catch (IOException e) {
}
finally {
input.close();
}
}
}
This currently displays only the name correctly. The balance is incorrect, and I don't know how to get the account number. In order to get the account number, I would need to get the position of name. In order to get the amount, I would need to seek name, offset 9 bytes, then read the next 8 bytes...
If you want to parse a text file that contains last names and amounts similar what you provided:
example provided
LastName 93942.12
What I would do is to try something like the following
public void read_file(){
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("C:\\Users\\Alos\\Desktop\\test.txt");
// Use DataInputStream to read binary NOT text.
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
int record = 0;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
String[] splits = strLine.split("\t");
String LastName = splits[0];
String Amount = splits[1];
System.out.println("Account Number: " + record + " Name: " + LastName + ", amount: " + Amount);
record++;
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
This might not be exactly what you're looking for but please take a look and update your question if you would like something different.
I it's not a homework, I would strongly recommend to use some RDBMS like Derby or MySQL.

Categories

Resources