I wrote this simple script that reads a text file and then adds the data to an array however i only want to print the first and last name of the students that have over 90 credits
Student[] student = new Student[50];
Scanner userin, filein;
String filename;
int numStudents;
// Get the filename from the user, with exception handling to deal with incorrect file names
userin = new Scanner(System.in);
filename = null;
filein = null;
filename = Students.txt;
try {
filein = new Scanner(new FileReader(filename)); // try to open the file
} catch (FileNotFoundException e) { // failed to open the file
System.out.println("Invalid file - try again");
filename = null;
}
numStudents = 0;
while (filein.hasNext()){
String lastName = filein.next();
String firstName = filein.next();
double gpa = filein.next();
int Credits = filein.next();
student[numStudents++] = new Student(lastName,firstName,gpa,Credits);
}
int i=0;
do
{
System.out.println(student[i].toString());
i++;
}
while ((student[i] != null)&&(i <= student.length));
"script"?
This is some ugly code. Formatting and structure matter. I'd recommend paying more attention to it in the future. It'll make your maintenance life easier as your programs (aka "scripts") become more complex.
Learn the Sun Java coding standards. You aren't following them now.
Everything in Java has to be a part of a class. I'll assume that you know that. This must be a snippet you cut out of your class.
Your code is too chaotic to worry about making it nice. This'll work:
if (student[i].getCredits() >= 90)
System.out.println(student[i].toString());
Related
I've written a class for a program designed to help manage a volleyball team's roster. The roster is contained in a .dat file and the players are written as follows:
Rachael Adams 3.36 1.93
My issue arises when I try to separate this string into the proper data types (the name being a string, then the first and second values being doubles for the stats).
public Roster(String filename) {
players = new ArrayList<Player>();
try {
FileReader fr = new FileReader(filename);
BufferedReader inFile = new BufferedReader (fr);
String line = inFile.readLine();
Scanner scan = new Scanner(line);
while(line != null) {
String firstName = scan.next();
String lastName = scan.next();
double attackStat = scan.nextDouble();
double blockStat = scan.nextDouble();
String name = firstName + " " + lastName;
Player newPlayer = new Player(name, attackStat, blockStat);
players.add(newPlayer);
line = inFile.readLine();
}
scan.close();
inFile.close();
} catch (IOException e) {
System.out.println(e);
}
}
The program throws this exception when a Roster object is created
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextDouble(Scanner.java:2564)
at Roster.<init>(Roster.java:30)
at Assignment08.openRosterFile(Assignment08.java:59)
at Assignment08.main(Assignment08.java:18)
I am newer to Java and still facing a learning curve, so if there is more information needed then please let me know.
If at all possible, I would greatly appreciate an explanation as to what I did wrong rather than just a solution. Thank you very much.
I always find it easier to split the line:
String[] columns = line.split(" (?=\\d)";
String name = columns[0];
double attackStat = Double.parseDouble(columns[1]);
double blockStat = Double.parseDouble(columns[2]);
This works by splitting on a space, but only when the next char is a digit via the look ahead (?=\d).
This automatically caters for any number of words in the name.
I'm very new (6 weeks into java) trying to remove elements from a csv file that lists a set of students as such (id, name, grades) each on a new line.
Each student id is numbered in ascending value. I want to try and remove a student by entering the id number and I'm not sure how I can do this.
So far I've just tried to reduce the value that user inputs to match the index as students are listed by number and I did this in a while loop. However, each iteration doesn't recognize the reduction from the previous user Input, and I think I need a way that can just search the value of the id, and remove the entire line from the csv file.
Have only tried to include the pertinent code. Reading previous stack questions has shown me a bunch of answers related to nodes, which make no sense to me since I don't have whatever prerequisite knowledge is required to understand it, and I'm not sure the rest of my code is valid for those methods.
Any ideas that are relatively simple?
Student.txt (each on a new line)
1,Frank,West,98,95,87,78,77,80
2,Dianne,Greene,78,94,88,87,95,92
3,Doug,Lei,78,94,88,87,95,92
etc....
Code:
public static boolean readFile(String filename) {
File file = new File("C:\\Users\\me\\eclipse-workspace\\studentdata.txt");
try {
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()) {
String[] words=scanner.nextLine().split(",");
int id = Integer.parseInt(words[0]);
String firstName = words[1];
String lastName = words[2];
int mathMark1 = Integer.parseInt(words[3]);
int mathMark2 = Integer.parseInt(words[4]);
int mathMark3 = Integer.parseInt(words[5]);
int englishMark1 = Integer.parseInt(words[6]);
int englishMark2 = Integer.parseInt(words[7]);
int englishMark3 = Integer.parseInt(words[8]);
addStudent(id,firstName,lastName,mathMark1,mathMark2,mathMark3,englishMark1,englishMark2,englishMark3);
}scanner.close();
}catch (FileNotFoundException e) {
System.out.println("Failed to readfile.");
private static void removeStudent() {
String answer = "Yes";
while(answer.equals("Yes") || answer.equals("yes")) {
System.out.println("Do you wish to delete a student?");
answer = scanner.next();
if (answer.equals("Yes") || answer.equals("yes")) {
System.out.println("Please enter the ID of the student to be removed.");
//tried various things here: taking userInput and passing through linkedlist.remove() but has never worked.
This solution may not be optimal or pretty, but it works. It reads in an input file line by line, writing each line out to a temporary output file. Whenever it encounters a line that matches what you are looking for, it skips writing that one out. It then renames the output file. I have omitted error handling, closing of readers/writers, etc. from the example. I also assume there is no leading or trailing whitespace in the line you are looking for. Change the code around trim() as needed so you can find a match.
File inputFile = new File("myFile.txt");
File tempFile = new File("myTempFile.txt");
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String lineToRemove = "bbb";
String currentLine;
while((currentLine = reader.readLine()) != null) {
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)) continue;
writer.write(currentLine + System.getProperty("line.separator"));
}
writer.close();
reader.close();
boolean successful = tempFile.renameTo(inputFile);
So I want to create a constructor that reads in a line of a file from a csv and save the first token into a variable and the remaining tokens into an array. This constructor will be used in a gradebook application but being new to txt/file manipulation I'm having a hard time.
A line will look like:
Billy Bob,68,79,95,83
I want to separate the tokens into these:
name = Billy Bob
grades[] = "68,79,95,83"
here is the code I have so far:
import java.io.*;
public class gradeBook {
public static void main(String[] args){
System.out.println("Java Grade Book version 1.0");
int lineCounter = 0;
String array[];
try{
File data = new File("/file/path/that/works");
InputStream f = new FileInputStream(data);
BufferedReader br = new BufferedReader(new InputStreamReader(f));
for (String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println(line); // just here to check that the code is working thus far
//insert code here
//name should equal first token (which is two names like Billy Bob)
//grades[] should contain the other double type tokens (e.g. 56,87,89,90)
}
br.close();
}
catch(Exception e){
System.err.println("Error: File Couldn't Be Read");
}
}
}
And I want to loop through the file to get as many students as are on the file stored so I can manipulate the grades for averages among other things. This is a personal project to help improve my developing skills so any help, useful tutorial links, and tips will be greatly appreciated. But please don't suggest simplistic examples like the many tutorials I have already read that only use one data type.
Thanks for any help!
Split the line into an array;
String[] input = line.split(",");
String variable = input[0];
int[] grades= new int[input.lenght - 2];
for(int i = 1; i < input.length; i++)
{
grades[i] = input[i];// you might have to do Integer.pareseInt(input[i]);
}
I did not write this in an IDE, but the logic should be correct.
You are going to run into a new problem. You grade book will only contain the last entry. Try using a 2D array for grades and 1D array for names; I personally would not use arrays. I would use arraylist.
So I haven't tested computing my tokens with methods or anything else yet but I have tokenized the line to sum (ha ha oops, meant some) degree with this bit of code:
String[] tokens = line.split(",");
String name = tokens[0];
String grade1 = tokens[1];
String grade2 = tokens[2];
String grade3 = tokens[3];
String grade4 = tokens[4];
My task is to read a text file in chunks of 64 characters, and use 2 different processes called Substitution and Column Transposition to encrypt it. Then, I have to decrypt it and write it out to another file.
I have written and tested out both processes of encrypting and decrypting and it worked wonderfully. But then I tried to loop the processes in case more than 64 characters were in the input file.
As a test case, I tried a 128 character input file. Unfortunately, the result only gives me the first 64 characters twice. I've tracked the scanner position and it goes beyond 64, but the characters read start back from 0. I'm not sure what the problem is.
Here is the relevant part of my code:
public static void main(String[] args) {
//Declare variables
Scanner console = new Scanner(System.in);
String inputFileName = null;
File inputFile = null;
Scanner in = null;
do
{
//Check if there are enough arguments
try
{
inputFileName = args[1];
}
catch (IndexOutOfBoundsException exception)
{
System.out.println("Not enough arguments.");
System.exit(1);
}
catch (Exception exception)
{
System.out.println("There was an error. Please try again.");
System.exit(1);
}
//Check if Input File is valid
try
{
inputFile = new File(inputFileName);
in = new Scanner(inputFile);
outputFile = new File(outputFileName);
out = new Scanner(outputFile);
}
catch (FileNotFoundException exception)
{
System.out.println("Could not find input file.");
System.exit(1);
}
catch (Exception exception)
{
System.out.println("There was an error. Please try again.");
System.exit(1);
}
} while (outputFileName != null && !inputFile.exists());
//Encryption
//Prepare patterns
String subPattern = CreateSubstitutionPattern(hash);
int[] transPattern = CreateTranspositionPattern(hash);
//Apply patterns
String textContent = "";
String applySub = "";
String applyTrans = "";
do
{
textContent = Read64Chars(in);
applySub = applySub + ApplySubstitutionPattern(textContent, subPattern);
applyTrans = applyTrans + ApplyTranspositionPattern(applySub, transPattern);
} while (in.hasNext());
//Decryption
String encryptContent = "";
Scanner encrypt = new Scanner(applyTrans);
String removeTrans = "";
String removeSub = "";
do
{
encryptContent = Read64Chars(encrypt);
System.out.println(applyTrans);
removeTrans = removeTrans + RemoveTranspositionPattern(encryptContent, transPattern);
removeSub = removeSub + RemoveSubstitutionPattern(removeTrans, subPattern);
} while (encrypt.hasNext());
console.close();
in.close();
encrypt.close();
System.out.println(removeSub); //For temporary testing
}
public static String Read64Chars (Scanner in)
{
String textContent = "";
in.useDelimiter("");
for (int x=0; x<64; x++)
{
if (in.hasNext())
{
textContent = textContent + in.next().charAt(0);
}
}
return textContent;
}
Do note that I have more variables to fill in args[0] and args[2] but I removed them for simplicity.
I would like to know if it is true that once a scanner reads a portion of it's input, it "consumes" it, and that portion gets removed. Does the scanner reset itself when declared again through a method? For example, does the declaration only point to the input source of the original scanner, or the actual scanner with its current properties?
encrypt is a diffrent Scanner from in, which you advance by 64 characters when you first call Read64Chars. So, encrypt starts at the first character when you call Read64Chars(encrypt). It seems like you want to use the same Scanner both times.
Also, in the future please name your functions starting with a lowercase letter. I felt dirty typing that... :)
A proper solution to get the whole encrypted text would be a code like this
public static String encryptedTextFile (Scanner in)
{
//ArrayList<String> stringBlocksOf64Chars = new ArrayList<String>();
StringBuilder encryptedTxt = new StringBuilder();
String currentTxt = "";
while (in.hasNextLine()) {
String line = currentTxt + in.nextLine();
currentTxt = "";
int i = 0;
for( ; i < line.length()/64 ; i++){
currentTxt = line.substring(i * 64, (i+1)*64);
//TODO - encrypt the text before adding it to the list
encryptedTxt.append(currentTxt);//encryptedTxt.append(encrypt(currentTxt));
}
currentTxt = line.substring(i * 64, line.length());
}
encryptedTxt.append(currentTxt);
/*for(String str : stringBlocksOf64Chars)
System.out.println(str);*/
return encryptedTxt.toString();
}
Your loop for (int x=0; x<64; x++) makes sure that you read only first 64 characters always and not the complete file. To get around that you should actually read whole file line by line.
The above code block follows this idea.
Steps to break down the logic.
Read the file line by line using scanner.
Break each line into chunks of 64 characters and encrypt the block 64 characters at a time
Generate encrypted text adding the encrypted 64 characters.
Whatever you do first break down the logic/steps you want to use in your code to make it simpler to understand or code.
Break the lines into 64 characters
I'm working on a school programming lab and I've gotten stuck. The book is not too helpful in teaching how to format I/O properly, or at least I'm not understanding it properly. I need a bit of help getting on with the next steps, but here's the full requirements of the program I'm supposed to be making:
A hotel salesperson enters sales in a text file. Each line contains
the following, separated by semicolons: The name of the client, the
service sold (such as Dinner, Conference, Lodging, and so on), the
amount of the sale, and the date of that event. Write a program that
reads such a file and displays the total amount for each service
category. Display an error if the file does not exist or the format is
incorrect. In addition to the program specifications listed, your
program should both print the results as well assend the results to a
separate output file.
Example of input.txt:
Elmer Fudd;Lodging;92.00;11-01-2014
Elmer Fudd;Conference;250.00;11-02-2014
Daffy Duck;Dinner;19.89;11-02-2014
Daffy Duck;Conference;275.00;11-02-2014
Mickey Mouse;Dinner;22.50;11-02-2014
Mickey Mouse;Conference;275.00;11-02-2014
I'm currently stuck on figuring out how to get the file properly loaded and formatted, which I think I did right, but then my professor suggested breaking each into it's own line, but nowhere in my book does it clearly tell how to do that. Just to be clear, I'm not looking for a coding miracle, I just would like someone to help guide me in the right direction as to what I should do next. Possibly a better way to handle this situation in a nicely detailed guide? Nothing fancy though. Thank you in advance, and here's my current code.
import java.util.*;
import java.io.*;
public class Sales
{
public static void main(String[] args) throws FileNotFoundException
{
File inputFile = new File("input.txt");
Scanner in = new Scanner(inputFile);
PrintWriter out = new PrintWriter("output.txt");
double dinnerTotal = 0;
double conferenceTotal = 0;
double lodgingTotal = 0;
Scanner lineScanner = new Scanner(inputFile);
lineScanner.useDelimiter(";");
while (lineScanner.hasNext())
{
String line = in.nextLine(); //Here's where I'm really stuck
System.out.print(line); //Not to say I'm not stumped all over.
}
in.close();
out.close();
lineScanner.close();
}
}
From what Jason said, I'm at this now:
import java.util.*;
import java.io.*;
public class Sales
{
public static void main(String[] args) throws FileNotFoundException
{
File inputFile = new File("input.txt");
Scanner in = new Scanner(inputFile);
PrintWriter out = new PrintWriter("output.txt");
double dinnerTotal = 0;
double conferenceTotal = 0;
double lodgingTotal = 0;
while (in.hasNext())
{
String line = in.nextLine();
String[] parts = line.split(";");
if(parts[1].equals("Conference")) {
conferenceTotal += Double.parseDouble(parts[2]);
} else if(parts[1].equals("Dinner")) {
dinnerTotal += Double.parseDouble(parts[2]);
} else if(parts[1].equals("Lodging")) {
lodgingTotal += Double.parseDouble(parts[2]);
}
}
in.close();
out.close();
}
}
Stick to one scanner.
Read each line in total, rather than breaking on the ';'.
Then use String.split() to break the line of text apart at the ';' separator.
Then check the second part (zero based index) to retrieve the service category and add the value in the third part to the relevant total.
String line = in.nextLine();
String[] parts = line.split(";");
if(parts[1].equals("Conference")) {
conferenceTotal += Double.parseDouble(parts[2]);
} else if(parts[1].equals("Dinner")) {
dinnerTotal += Double.parseDouble(parts[2]);
} else if(parts[1].equals("Lodging")) {
lodgingTotal += Double.parseDouble(parts[2]);
}