How to modify a text file using Java? - java

http://pastebin.com/E5TspHfK - Object Class, named PhoneBookEntryhttp://pastebin.com/Ce94SJzB - Method Class, named PhoneBook
http://pastebin.com/ENsVT0jJ - Tester Class, named PhoneBookTester
Basically my aim with these three classes is to make a "Phone Book" -- a text-based program that allows people to create a database of their contacts that they can add entries to, edit/delete/display the entries of, search, and sort the entries.
The PhoneBookEntry object array that the program is creating is output to a text file, which displays them in the format "fName\tlName\tnumber". These are obviously the various variables that can be stored in the PhoneBookEntry class.
The question is, to write to the text file I have to use the PrintWriter class, but how do I make it so that the text file is updated if the order of the array is rearranged? Because I don't send added entries to the array, I send them to the text file itself, but if you use the sort or edit function, you modify the content of the array, not the text file.
So how do I make it possible to modify the contents of the text file itself if you can't 'write backwards' with the PrintWriter class? Relevant bits of code are pasted below.
PhoneBook:
public static int filledTil=-1;
FileWriter fw = new FileWriter("C:\\Users\\Hana\\Desktop\\PhoneBook.txt");
PrintWriter output = new PrintWriter(fw);
static PhoneBookEntry[] phoneBook = new PhoneBookEntry[500];
public PhoneBook() throws IOException {
Scanner input = new Scanner(new File("C:\\Users\\Hana\\Desktop\\PhoneBook.txt"));
while(input.hasNext()){
Scanner sc = new Scanner(input.nextLine());
String fName = sc.next();
String lName = sc.next();
String number = sc.next();
filledTil++;
phoneBook[filledTil] = new PhoneBookEntry(fName, lName, number);
}
input.close();
}
PhoneBook Sort Methods
public static int partition(){
int lo = 0;
int hi = filledTil;
PhoneBookEntry temp;
PhoneBookEntry pivot = phoneBook[(lo + hi) / 2];
while(lo <= hi){
while(phoneBook[lo].lName.compareTo(pivot.lName) < 0){
lo++;
}
while(phoneBook[lo].lName.compareTo(pivot.lName) > 0){
hi--;
}
if(lo <= hi) {
temp = phoneBook[lo];
phoneBook[lo] = phoneBook[hi];
phoneBook[hi] = temp;
lo++;
hi--;
}
};
return lo;
}
public static void quickSort(int lo, int hi){
int index = partition();
if(lo < (index - 1)){
quickSort(lo, (index-1));
}
if(index < hi){
quickSort(index, hi);
}
}
PhoneBook Quit Method
public void quit(){
output.close();
System.exit(0);
}

Related

inserting onto a BST, "The method insert(myclass.TreeNode, int) is undefined for the type myclass"

I'm a beginning Java student and have a homework assignment which requires me to build a simple BST using recursion. Should be simple, but it's giving me some trouble.
The Constructor Class and main() method are provided to me as follows
public static class TreeNode
{
TreeNode LeftLink;
int Content;
TreeNode RightLink;
}
// end class TreeNode
public static void main(String[] args) throws IOException
{
TreeNode T = null;
int H, i;
T = BuildSearchTree();
H = Height(T);
System.out.println("The number of nodes on the tree is " + NodeCount(T));
System.out.println("The height of the tree is " + H);
for (i = 0; i <= H; i++)
System.out.println("The number of nodes on level " + i + " is " + CountLevel(T,i));
// end for
}
My task is to fill to create a BinarySearchTree method without modifying anything already provided to me.
The BinarySearch Tree method requests a file filled with integers from the user, and recursively builds a BST from it.
My Compiler (Eclipse) is giving me an error under the title of my insert method "The method insert(myclass.TreeNode, int) is undefined for the type myclass"
I believe this has something to do with the way T=BuildSearchTree(); is declared in the main method, but frankly, I have no idea what's going on.
What I have so far is
public static TreeNode BuildSearchTree() throws IOException {
Scanner Keyboard = new Scanner(System.in);
System.out.println("enter the name of your word file (please include ''.data'' or ''.txt'' when inputting file name) (number of words in the word file must be less than 30.)");
String datafile = Keyboard.next();
Scanner InputFile = new Scanner(new File(datafile));
int[] data = new int[1000];
while(InputFile.hasNext()){
int i;
data[i]=InputFile.nextInt();
i++;
} //end while
for(int i=0; i<1000; i++){
TreeNode T = insert(T, data);} //end for
private static TreeNode insert(TreeNode node, int content)
{
if (node == null)
{
node.Content=content;
}
else if (content <= node.Content)
{
insert(node.LeftLink, content);
}
else
{
insert(node.RightLink, content);
}
}
return node;
}//end insert method
return T;
}//end BuildSearchTree
Java does not allow nested functions, so finish the code BuildSearchTree() before starting the code for insert().
The call to insert in T = insert(T, data); should be something like T = insert(T, data[i]);
You need to declare T outside the loop if you want to use it after the loop.
You can't assume that the data file has less than 1000 elements, so you probably want to use a java.util.ArrayList rather than an array. You need to use the number of items actually read from the file in the loop around the call to insert rather than the literal value of 1000.
Your while loop should be something like:
ArrayList<Integer> data = new ArrayList<Integer>;
while(InputFile.hasNext()){
data.add(InputFile.nextInt());
} //end while
TreeNode T = new TreeNode();
for(i=0; i<data.length(); i++){
T = insert(T, data[i]);
} //end for
return T;

read lines from external file and store elements in array

I am new here so please show some patience. I am trying to read the data from an external file and store the info in 2 arrays.
The file looks like this:
0069 723.50
0085 1500.00
0091 8237.31
I am using 2 scanners to read the input and I think they work ok because when I try to print, the result looks ok.
My first problem is that I am able to read the first numbers on the list using nextInt(), but cannot use nextDouble() for the double ones as I get the "java.util.InputMismatchException" message. For that reason I read it as a String. The part with the other two scanners is supposed to do what the first parts should do, for a different input file, but the problem is the same.
My next and biggest problem, until now, is that am not able to store the values from the two columns in two distinct arrays. I have tried several ways (all commented) but all fail. Please help and thanks.
Here is my code:
import ui.UserInterfaceFactory;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Scanner;
import ui.UIAuxiliaryMethods;
public class Bank {
static final int MAX_NUMBER_OF_ACCOUNTS = 50;
PrintStream out;
Bank(){
UserInterfaceFactory.enableLowResolution(true);
out = new PrintStream(System.out);
}
void readFiles(){
Scanner balanceFile = UIAuxiliaryMethods.askUserForInput().getScanner();
while(balanceFile.hasNextLine()){
String balance_Line = balanceFile.nextLine();
Scanner accountsFile = new Scanner(balance_Line);
int account = accountsFile.nextInt(); //works
out.printf("%04d ",account);
/*int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS]; //does not store the values properly
int account = accountsFile.nextInt();
for(int j=0; j < accounts_array.length; j++){
accounts_array[j] = account;
}*/
/*int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS]; //java.util.InputMismatchException
for(int j=0; j < accounts_array.length; j++){
accounts_array[j] = accountsFile.nextInt();
//out.printf("%04d \n",accounts_array[j]);
}*/
String balance = accountsFile.nextLine(); //problem declaring balance as a double
out.printf("%s\n",balance);
/*String [] balance_array = new String [MAX_NUMBER_OF_ACCOUNTS]; //java.util.NoSuchElementException
for(int j=0; j < balance_array.length; j++){
accountsFile.useDelimiter(" ");
balance_array[j] = accountsFile.next();
//out.printf("%04d \n",accounts_array[j]);
}*/
}
Scanner mutationsFile = UIAuxiliaryMethods.askUserForInput().getScanner();
while(mutationsFile.hasNext()){
String mutation_Line = mutationsFile.nextLine();
Scanner mutatedAccountsFile = new Scanner(mutation_Line);
int mutated_account = mutatedAccountsFile.nextInt();
out.printf("%04d ",mutated_account);
int action = mutatedAccountsFile.nextInt(); //deposit or withdrawal
/*if (action == 1){
}else{
}*/
out.printf(" %d ",action);
/*Double amount = mutatedAccountsFile.nextDouble();
out.printf(" %5.2f ",amount);*/
String amount = mutatedAccountsFile.nextLine();
out.printf("%s\n",amount);
}
}
void start(){
new Bank();readFiles();
}
public static void main(String[] args) {
new Bank().start();
}
}
The InputMismatchException occurs because you try to read a double using the nextInt() function. To solve this issue, you can first read the tokens as Strings using the next() function and convert them appropriately.
while(mutationsFile.hasNext()){
mutation_Line = mutationsFile.next();
if(mutation_Line.indexOf(".") == -1)
//token is int
else
//token is double
}
Since you already know what the contents of the two columns are, you can store the integers and doubles in two lists and then, if you want, get them into an array.
List<Integer> intList = new ArrayList<Integer>();
List<Double> doubleList = new ArrayList<Double>();
Now replace the if statements in the first snippet with this:
if(mutation_Line.indexOf(".") == -1)
intList.add(new Integer(Integer.parseInt(mutation_Line)));
else
doubleList.add(new Double(Double.parseDouble(mutation_Line)));
In the end, you can get them into arrays:
Object[] intArr = intList.toArray(),
doubleArr = doubleList.toArray();
//display the contents:
for(int i=0; i<intArr.length; i++)
out.printf("%04d\t%.2f\n", Integer.parseInt(intArr[i].toString()),
Double.parseDouble(doubleArr[i].toString()));
OUTPUT:
0069 723.50
0085 1500.00
0091 8237.31
First off, you don't need to use 2 scanners. The Scanner object is simply reading your file, one scanner is plenty to accomplish the task of reading a file.
If you're trying to read the integers/doubles from file and are having trouble with nextInt() and nextDouble(), consider a different approach to parsing (e.g. parse the line into a string, split the line into 2 parts based on a space character, then trim both resulting strings and convert to respective integers/doubles).
Now back to the Scanner parsing the two values, remember first that when you use a next() or nextInt(), etc. those methods consume the next respective token. So parsing a line as a string from the file into another Scanner object is redundant and unnecessary in this case.
If you know your max number of accounts, and it's simply 50, then go ahead an allocate that prior to the while loop.
Here's an alternative approach with the code you posted.
public class App {
static int MAX_NUMBER_OF_ACCOUNTS = 50;
static PrintStream out;
static void readFiles() {
Scanner balanceFile = null;
try {
balanceFile = new Scanner(new File("C:\\Users\\Nick\\Desktop\\test.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (balanceFile == null)
return;
int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS];
double [] balance_array = new double [MAX_NUMBER_OF_ACCOUNTS];
int currentIndex = 0;
while (balanceFile.hasNextLine()) {
int account = balanceFile.nextInt();
double balance = balanceFile.nextDouble();
System.out.print("acc = " + account + " ");
System.out.println("bal = " + balance);
//out.printf("%04d ", account);
accounts_array[currentIndex] = account;
//out.printf("%s\n", balance);
balance_array[currentIndex] = balance;
currentIndex++;
}
balanceFile.close();
}
static void start() {
readFiles();
}
public static void main(String[] args) {
start();
}
}
Please note the excessive use of static could also be avoided in the future, but for the sake of the example it spread like the plague.
As you can see in the logic leading up to the while loop, the scanner object is made from a file I copied your example data into a file on my desktop. The arrays are allocated prior to the while loop (note: see #progy_rock and their use of ArrayList's - may help improve your code in the long run). And finally, note the index count to move the position along in the array to which you are inserting your lines to.

Using imported data Java

I'm just learning to use File I/O and struggling to figure out how to use the data. For example, I have a .txt file that is setup with a name and list of scores that apply to that name, each list ending with a -1. I have successfully imported the file and was able to print it on the console but I need to add this information to an ArrayList so I can sort it, find the high and low, and the average and median. When I attempt to enter the data into an ArrayList I get a Exception I don't know how to handle. Here is the code I have so far, any help would be appreciated.
public static void main(String[] args) throws IOException {
File file = new File("Project11input.txt");
Scanner inFile = new Scanner(file);
ArrayList<Integer> TerryCrews = readNextSeries(inFile);
int median = getMedian(TerryCrews);
System.out.println("The median is " + median);
int average = getAverage(TerryCrews);
System.out.println("The average is " + average);
}
private static ArrayList<Integer> readNextSeries(Scanner inScanner) {
ArrayList<Integer> Input = new ArrayList<Integer>();
int thesex = 0;
while(thesex >= 0){
thesex = inScanner.nextInt();
Input.add(thesex);
}
System.out.println("End of input");
return Input;}
private static int getMedian(ArrayList<Integer> inList) {
int last = 0;
int power = (inList.size()/2) - 1;
int pow=0;
int ful = power+1;
int wap =0;
int onetwo = inList.size()%2;
if(onetwo == 1){
last = inList.get(ful);}
else{
pow = inList.get(power);
wap = inList.get(ful);
last = (pow + wap);
last=last/2;
}
return last; }
to clarify, I basically need the numbers in the File "file" to be in an ArrayList so they can be used.

Java sorting text file with Comparable

I need a program that reads in data and sorts the file in descending order using quicksort based on the index provided for instance this is the data using comparable
adviser,32/60,125,256,6000,256,16,128,198,199
amdahl,470v/7,29,8000,32000,32,8,32,269,253
amdahl,470v/7a,29,8000,32000,32,8,32,220,253
amdahl,470v/7b,29,8000,32000,32,8,32,172,253
amdahl,470v/7c,29,8000,16000,32,8,16,132,132
And i need to sort by the 5th index(mmax) case 2 and the 6th(cache) case 3 and the ninth index(php) case 4 in descending order & print the first index which is already sorted case 1
The problems with my code are as follows:
It doesn't sort based off the index
It gives me an error at runtime with the code: Arrays.sort(c);
Please help with suggestions
Thanks
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Prog4 {
static Scanner input;
static File filename;
/**
* This function displays the menu for the user to choose an option from
*/
public void menu() {
System.out.println("Option 1: Sort by VENDOR: ");
System.out.println("Option 2: Sort decreasing number by MMAX: ");
System.out.println("Option 3: Sort decreasing number by CACH: ");
System.out.println("Option 4: Sort decreasing number by PRP: ");
System.out.println("Option 5: Quit program");
}
/**
* Constructor to handle the cases in the menu options
* #throws FileNotFoundException
* #throws IOException
*/
public Prog4() throws FileNotFoundException {
//Accepts user input
Scanner in = new Scanner(System.in);
//calls the menu method
menu();
//Initializes the run variable making the program loop until the user terminates the program
Boolean run = true;
//While loop
while (run) {
switch (in.nextInt()) {
case 1:
System.out.println("Option 1 selected");
System.out.println("Sorted by vendor:");
filename = new File("machine.txt");
//Instantiate Scanner s with f variable within parameters
//surround with try and catch to see whether the file was read or not
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Instantiate a new Array of String type
String array [] = new String[10];
//while it has next ..
while (input.hasNext()) {
//Initialize variable
int i = 0;
//store each word read in array and use variable to move across array array[i] = input.next();
//print
System.out.println(array[i]);
//so we increment so we can store in the next array index
i++;
}
case 2:
System.out.println("Press any key to continue");
Scanner input2 = new Scanner(System.in);
String x = input2.nextLine();
if (x.equals(0)) continue;
System.out.println("Option 2 selected") ;
Computer[] c = new Computer[10];
filename = new File("machine.txt");
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Arrays.sort(c);
while (input.hasNextLine()) {
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
}
}
}
/**
* Main method
* #param args
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
//Calls the constructor
new Prog4();
//static Scanner input;
}
public static void quickSort(int arr[], int left, int right) {
if (left < right) {
int q = partition(arr, left, right);
quickSort(arr, left, q);
quickSort(arr, q+1, right);
}
}
private static int partition(int arr[], int left, int right) {
int x = arr[left];
int i = left - 1;
int j = right + 1;
while (true) {
i++;
while (i < right && arr[i] < x)
i++;
j--;
while (j > left && arr[j] > x)
j--;
if (i < j)
swap(arr, i, j);
else
return j;
}
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Comparator class:
import java.util.Comparator;
class Computer implements Comparable<Computer> {
private String vendor;
private int mmax;
private int cach;
private int php;
public Computer(int value) {
this.mmax = value;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public int getMmax() {
return mmax;
}
public void setMmax(int mmax) {
this.mmax = mmax;
}
public int getCach() {
return cach;
}
public void setCach(int cach) {
this.cach = cach;
}
public int getPhp() {
return php;
}
public void setPhp(int php){
this.php = php;
}
#Override
public int compareTo(Computer m) {
if (mmax < m.mmax) {
return -1;
}
if (mmax > m.mmax) {
return 1;
}
// only sort by height if age is equal
if (cach > m.cach) {
return -1;
}
if (cach < m.cach) {
return 1;
}
if (php > m.php) {
return -1;
}
if (php < m.php) {
return 1;
}
return 0;
}
public static Comparator<Computer> ComparemMax = new Comparator<Computer>() {
#Override
public int compare(Computer p1, Computer p2) {
return p2.getMmax() - p1.getMmax();
}
};
}
The biggest problem is that the Computer classes do not get instantiated for each line that gets read.
As you want to have different sort options depending on the user input, you can not let the Computer class determine the compare method, but instead you will need to create a separate Comparator implementation for each sort option. Next, make the file read operation generic and abstract it away in a separate method call from each selected case. Instead of an array of Computers, I would make it a List or a Set, because you don't (want to) know the length up front.
I would like to lay out the steps in detail so that you could figure out each step for yourself. You have got a lot of it right.. but there are gaps.
Create a Computer class. It should have a constructor which takes a single String and splits it using the separator ',' and parses each part to String/int as applicable. (It would be preferable for you to parse and store the whole string.. which means you can have 10 fields in your class)
Create a blank ArrayList to store the Computer objects.
Iterate through the file and readLine
Call the Computer constructor using the String representing each line in the file within the while loop
Add the new Computer object to the computers ArrayList
Write 5 different comparators.
Based on user input, instantiate the correct comparator and pass it to the sort method
Print the sorted array
If you still face a problem, mention the specific point at which you like more clarity..

How to sort a large text file into a multi-dimensional array?

I'm trying to read a large text file and sort it into a 3D array using scanner() but I don't think the array is being populated, and I keep getting the error java.lang.NullPointerException, but I suspect there is more going wrong than just that.
I'm currently trying to use nested for loops to sort out the year, month, and each date.
Another thing that I'd like to do is change the array from String to int but it's having none of it.
Here is my code:
public class GetData {
public String[][][] sortedData;
private Scanner rainFile;
//method for opening the file
public void openFile() {
try{
rainFile = new Scanner(new File("myfile.txt"));
}
catch(Exception e){
System.out.println("Could not find file");
}
}
//method for reading the file
public void readFile(){
int month = 0;
int day = 0;
//this loop sorts each year
for(int l = 0; l < 34; l++){
String a = rainFile.next();
sortedData[l][month][day] = a;
//this loop sorts every month of each year
for(int i = 0; i < 12; i++){
String b = rainFile.next();
sortedData[l][i][day] = b;
month++;
//this loop sorts each individual entry of every month
for(int j = 0; j < 31; j++){
String c = rainFile.next();
sortedData[l][i][j] = c;
day++;
}
}
}
}
//close the file once it's been used
public void closeFile(){
rainFile.close();
}
//test method to see if array is full
public void arrayTest(){
System.out.print(sortedData[1][1][1]);
}
}
Many thanks.
Create instance first
public String[][][] sortedData = new String[n][n2][n3]; //n1 n2 n3 dimension size
You forgot this:
sortedData = new String[34][12][31];

Categories