How to sort blocks of text lines in file? - java

I have a text file consisting of ID, persons name and surname, bank balance and date of account creation. I somehow need to sort this text file by surname and balance, but I don't know how.
ID:41
Name and surname: Andris Lietis
Balance: 30000 Eur
Created: 31.03.2019
ID:33
Name and surname: Rainis Maize
Balance: 2000 Eur
Created: 32.03.2019
ID:34
Name and surname: Akmens Liepins
Balance: 123 Eur
Created: 29.03.2019
ID:35
Name and surname: Karlis Maiznieks
Balance: 32000 Eur
Created: 04.04.2019
So I was first thinking about somehow reading that file and when I approach one of ID line, I read next three lines and somehow storing those 4 lines in some sort of a block/variable, then doing the same with other blocks. My friend mentioned making objects and comparing, but I don't have any experience with that and as I look up in the google, this really confuses me.
public static void Sakartosana(String nosaukums) throws IOException {
br = new BufferedReader(new FileReader(nosaukums));
String s;
//I understand that I need to somehow sort this with selection.sort
ArrayList<String> al = new ArrayList<String>();
while ((s = br.readLine()) != null) {
if (s.startsWith("ID:")) {
}
}
br.close();
}
This is how I read the line by line, I have many methods with different tasks reading file like this.
The expected result would be like this :
ID:41
Name and surname: Andris Lietis
Balance: 30000 Eur
Created: 31.03.2019
ID:34
Name and surname: Akmens Liepins
Balance: 123 Eur
Created: 29.03.2019
ID:35
Name and surname: Karlis Maiznieks
Balance: 32000 Eur
Created: 04.04.2019
ID:33
Name and surname: Rainis Maize
Balance: 2000 Eur
Created: 32.03.2019

Related

How can I store my user input in a Driver to my variables in a Class?

I'm still new to Stack and Java so let me clarify the question as best as I can. I'm currently learning OOP in Java and I have an assignment that requires us to create a voucher system where essentially the user inputs some information about a purchase, that information is assigned to a voucher, and then once paid the voucher is then assigned a check number.
Now, I have the Voucher Class set up and I believe it's set up correctly, but my issue is with the VoucherDriver. My VoucherDriver has all of the code for the user input, and my VoucherClass has all of my variables and my array for the vouchers themselves. Here is the VoucherClass code:
public class Voucher {
private static int nextVoucherNumber, nextCheckNumber;
private int _voucherNumber,_checkNumber;
private static Voucher[] vouchers;
private String _purchaseDate, _paymentDate, _debitAccount, _vendor;
private double _amount;
Voucher(String purchaseDate, double amount, String debitAccount, String vendor) {
this._purchaseDate = purchaseDate;
this._amount = amount;
this._debitAccount = debitAccount;
this._vendor = vendor;
this._voucherNumber = nextVoucherNumber;
//checks if the array is full
for (int i = 0; i < vouchers.length; ++i) {
if (vouchers[i] == null) {
vouchers[i] = this;
nextVoucherNumber++;
break;
}
}
}
//must call this method first to initialize the vouchers
public static void initialize(int firstVoucher, int firstCheck, int maxNumberOfVouchers) {
nextVoucherNumber = firstVoucher;
nextCheckNumber = firstCheck;
vouchers = new Voucher [maxNumberOfVouchers];
}
public static Voucher find(int voucherNumber) {
for (Voucher v : vouchers) {
if (v != null && v._voucherNumber == voucherNumber) {
return v;
}
}
return null;
}
public static void printData() {
int count = 0;
for (Voucher v : vouchers) {
if (v != null) {
System.out.println(v);
count++;
} else {
break;
}
}
if (count == 0) {
//System.out.println("No Data.");
}
}
#Override
public String toString() {
return "Voucher #" + _voucherNumber + " Date: " + _purchaseDate + " Amount:$" + _amount + "\n"
+ "Account: " + _debitAccount + " Vendor: " + _vendor + "\n" + "Check #:" + _checkNumber + " Date:" + _paymentDate + "\n";
}
public void issueCheck(String paymentDate) {
this._paymentDate = paymentDate;
this._checkNumber = nextCheckNumber;
nextCheckNumber++;
}
}
How can I set the users input on the VoucherDriver, to equal a variable or method on the VoucherClass? Is that even possible or am I going in circles for no reason? I'll post some code snippets from my VoucherDriver below for extra clarification:
public class VoucherDriver {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int choiceSelection;
Voucher.initialize(1001, 2001, 10);
System.out.println("XYZ COMPANY Voucher Manager \n");
do {
System.out.println("Activities available: \n "
+ "1.Create a voucher \n "
+ "2.Print a voucher register \n "
+ "3.Issue checks");
System.out.println("Enter number of choice (or zero to quit): ");
choiceSelection = sc.nextInt();
if (choiceSelection == 1) {
System.out.println("Enter purchase date (dd/mm/yyyy): ");
sc.next();
System.out.println("Enter amount: ");
sc.nextDouble();
System.out.println("Enter name of account to debit: ");
sc.next();
System.out.println("Enter name of vendor: ");
sc.next();
System.out.println();
}
if (choiceSelection == 2) {
System.out.println();
}
if (choiceSelection == 3) {
System.out.println("Enter number of voucher to pay: ");
sc.nextInt();
System.out.println("Enter payment date (dd/mm/yyyy): ");
sc.next();
}
} while (choiceSelection != 0);
}
}
Initially, I had set new variables in the Driver to store the user input, however, I don't think that would work since those variables won't be "connected" to the variables on the VoucherClass, hence the scanner sc not having variables set to the left within the if statement.
I also tried calling my Voucher constructor method but I don't think I even did that right when I attempted to do so. If anyone can provide some insight on what I'm doing incorrectly, I would be most grateful.
A user commented that adding the assignment specs may be helpful, here is the sample session:
XYZ COMPANY Voucher Manager
Activities available:
create voucher
print voucher register
issue checks
Enter number of choice (or zero to quit): 4
Invalid choice. Try again.
Activities available:
create voucher
print voucher register
issue checks
Enter number of choice (or zero to quit): 1
Enter purchase date (dd/mm/yyyy): 17/08/2003
Enter amount: $123.45
Enter name of account to debit: tools
Enter name of vendor: Mack's Hardware
Activities available:
create voucher
print voucher register
issue checks
Enter number of choice (or zero to quit): 1
Enter purchase date (dd/mm/yyyy): 15/09/2003
Enter amount: $67.42
Enter name of account to debit: supplies
Enter name of vendor: ABC Company
Activities available:
create voucher
print voucher register
issue checks
Enter number of choice (or zero to quit): 2
Voucher Register:
voucher #1001 date: 17/08/2003 amount: $123.45
account: tools vendor: Mack's Hardware
check #0 date: null
voucher #1002 date: 15/09/2003 amount: $67.42
account: supplies vendor: ABC Company
check #0 date: null
Activities available:
create voucher
print voucher register
issue checks
Enter number of choice (or zero to quit): 3
Enter number of voucher to pay: 1000
No vouchers have that number.
Enter number of voucher to pay: 1001
Enter payment date (dd/mm/yyyy): 08/01/2004
Activities available:
create voucher
print voucher register
issue checks
Enter number of choice (or zero to quit): 2
Voucher Register:
voucher #1001 date: 17/08/2003 amount: $123.45
account: tools vendor: Mack's Hardware
check #2001 date: 08/01/2004
voucher #1002 date: 15/09/2003 amount: $67.42
account: supplies vendor: ABC Company
check #0 date: null
Activities available:
create voucher
print voucher register
issue checks
Enter number of choice (or zero to quit): 0
Collection like a list will be better approach to store Vouchers - btw. you can create list of 'Voucher' as a field in VoucherDriver. Then you dont need to initialize your Vouchers.
Assign scanner.nextLine/nextInt/nextString to variable (for validation e.q. Date if needed) and create new Voucher object using constructor at the end of if statement in main method. And add object to the list.
You don't need to use underscore in class fields if you are using this.

how to use a while loop to read from text file

I need to be able to read 3 separate blocks of text from a file and display them including the calculations to the console using a while loop. At the moment I can only get one block of text to display.
I couldn't figure out how to format it on here exactly like it is in the text file so excuse the image.
Text File:
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
FileReader input = new FileReader ("rooms.txt");
Scanner console = new Scanner(System.in);
Scanner read = new Scanner (input);
final double defaultTax = .20;
System.out.println("Do you wish to specify a custom tax rate? (yes/no): ");
if (console.next().equals("yes")) {
System.out.println("What would you like the tax rate to be?");
}
//use while loop
else
{
while (read.hasNextLine()) {
String roomType = read.nextLine();
int rooms = read.nextInt();
double price = read.nextDouble();
double totalIncome = (double) (rooms*price);
double tax = (double) (price*rooms*defaultTax);
System.out.println("Room type: " + roomType + " | No. of rooms: " + rooms + " | Room price: " + price + " | income: " + totalIncome + " | tax: " + tax);
}
}
}
CURRENT OUTPUT: Room type: Single | No. of rooms: 5 | Room price: 23.5 | income: 117.5 | tax: 23.5
The desired output would include all of the data, including the calculations.
Current error message:
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.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at cwk/cwk.test1.main(test1.java:31)
I am literally just a uni student looking for a bit of help on a bit of one module. I'm not a programmer, I'm not doing a programming course. please don't delete my question.
The issue is related to whitespace. When you call nextLine it will read a whole line, until it encounters \n or the end of the file. When you call nextInt and nextDouble it will skip any preceding whitespace, however it will not consume any whitespace after.
So the first iteration of your while loop is working fine. However the next iteration when nextLine is called, then an empty string is returned. After that when nextInt is called, then it encounters "Double" and thus you get an InputMismatchException.
The easiest way to fix this, is that at the end of your while loop, you can skip all subsequent whitespace:
while (read.hasNextLine()) {
// Keep everything you already have
read.skip("\\s+");
}

Is there a clear way of initializing a loop that is terminated when a number is entered as a String?

So it's been about 6 months since I've done anything with coding as well as I'm still relatively new to it. I'm doing some review and the program asks for several attributes, in which one is a string asking for an employee's ID #. It is supposed be in a loop, in which the loop is terminated when the user enters 0 for their employee ID. I have the program working up until this point and I haven't created the loop yet which is where I am stuck.
`import java.util.Scanner;`
`public class PayrollTester {`
`public static void main(String[] args) {`
`String empID;`
`float gross;`
`float ste;`
`float fed;`
`Scanner scnr = new Scanner(System.in);`
`System.out.println("Enter your Employee ID: ");`
`empID = scnr.nextLine();`
`System.out.println("Enter your Gross Pay: ");`
`gross = scnr.nextFloat();`
`System.out.println("Enter your State Tax Rate: ");`
`ste = scnr.nextFloat();`
`System.out.println("Enter your Federal Tax Rate: ");`
`fed = scnr.nextFloat();`
`Payroll empID1 = new Payroll(empID, gross, ste, fed);`
`System.out.println("The Net Pay for Employee " +
empID1.getEmplyeID() + " is " + empID1.calcNetPay());`
`}`
`}`
You can just do a while(true) loop and then you have an if statement right after they enter their employee id that checks to see if the value they entered is equal to 0.
while(true){
//get their employee id
if (empiID.equals("0")){
break;
}
//get more user inputs
}

How to parse a line of text with two separate pieces of data?

I'm new to parsing (and new to Java), so I just want to be sure I'm conceptualizing this correctly.
I've written a program that allows the user to paste text into a text field, then click the "parse data" button. This button parses the text for two pieces of data: a name and a number.
The text data is generally pasted by the user in this form:
john 48915
beth 10431
frank 10112
anne 34887
taserface 90090
bill 56448
I'm using the regular expression "^\d+\t.*\d+$" to detect the pattern, and after the pattern is confirmed, my parse data code does the following:
Scanner parser = new Scanner(inputText);
parser.useDelimiter("\\n");
while (parser.hasNext()) {
String nextToken = parser.next();
String name = nextToken.trim();
// how do I get the number?
You'll notice the \n delimiter, which parses data at the new line character. This breaks the data up into rows, but does not break each row into two separate data points. I need to grab both the name and the number separately.
I believe I should be using a space delimiter, but I'm not sure if I should be doing this in one or two different steps. The confusion, I believe, stems from my limited understanding of how the Scanner does its work. But after a review of the Java documentation, I'm still not really sure.
Current output:
john 48915
beth 10431
frank 10112
etc.
Expected output:
john
48915
beth
10431
etc.
Should I be doing two different loops of parsing, or can I get the work done in the same pass?
Your problem is that you are usimg \n as delimiter.
This leads to the behavior that the input you are passing to your scanner is only delimited at linebreaks and not as you are expecting also at whitespaces.
One solution would that would work is to simply delete the following line: parser.useDelimiter("\\n");
A solution that would also work is the following:
try (Scanner parser = new Scanner(inputText)) {
while (parser.hasNextLine()) {
String nextLine = parser.nextLine();
String[] strings = nextLine.split("\\s");
// Here you can use any pattern to split the line
String name = strings[0];
String number = strings[1];
System.out.printf("%s%n%s%n", name, number);
}
}
This leads to the following output:
john
48915
beth
10431
frank
10112
anne
34887
taserface
90090
bill
56448
The solution gives you some more controll over the lines and how to parse the name and number.
Here is an example implementation for your case, which offers more control and flexibility to accommodate change of delimiters -
import java.util.Arrays;
public class StringSplitExample {
public static void main(String []args){
String content = "john 48915\n"
+ "beth 10431\n"
+ "frank 10112\n"
+ "anne 34887\n"
+ "taserface 90090\n"
+ "bill 56448";
String[] dataset = content.split("\\n|\\s");
for (String value : dataset) {
System.out.println(value);
}
}
}
And, following is the output for the above code snippet -
john
48915
beth
10431
frank
10112
anne
34887
taserface
90090
bill
56448
You can achieve this functionality with String spilt method, below is same program and output as you desire.
I think without space user can not go next line while filling form.
public class ParseLineText {
public static void main(String[] args) {
String textData = "john 48915 " +
"beth 10431 " +
"frank 10112 " +
"anne 34887 " +
"taserface 90090 " +
"bill 56448 ";
String[] data = textData.split("\\s");
for (String text : data) {
System.out.println(text);
}
}
}
Output:
john
48915
beth
10431
frank
10112
anne
34887
taserface
90090
bill
56448

What is wrong with Java File read?

I deal with a file problem.
IBM 7918 Ayse Durlanik 7600 Computer
------------------------------------
Gama 2342 Mehmet Guzel 8300 Civil
------------------------------------
Lafarge 3242 Ahmet Bilir 4700 Chemical
------------------------------------
Intel 3255 Serhan Atmaca 9200 Electrical
------------------------------------
Bilkent 3452 Fatma Guler 2500 Computer
------------------------------------
Public 1020 Aysen Durmaz 1500 Mechanical
------------------------------------
Havelsan 2454 Sule Dilbaz 2800 Electrical
------------------------------------
Tai 3473 Fethi Oktam 3600 Computer
------------------------------------
Nurol 4973 Ayhan Ak 4100 Civil
------------------------------------
Pfizer 3000 Fusun Ot 2650 Chemical
------------------------------------
This is the text file and I don't want to read this =
"------------------------------------ "
Here is the method:
Scanner scn = null;
File fp = new File("C:/Users/Efe/Desktop/engineers.txt");
try {
scn = new Scanner(fp);
while (scn.hasNextLine()) {
{
if (!scn.next().equals("------------------------------------")) {
String comp = scn.next();
int id = Integer.parseInt(scn.next());
String name = scn.next();
String surname = scn.next();
double sal = Double.parseDouble(scn.next());
String area = scn.next();
Engineer e = new Engineer(comp, id, name, surname, sal, area);
list.add(e);
}
}
scn.close();
}
This is the code where I get an exception at run-time:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException:
For input string: "Ayse" at
java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
What is wrong with the code?
You're off by one...in the line
if (!scn.next().equals("------------------------------------")) {
if the next token is not the dashed line, then it is lost. Consider assigning it to a temporary variable.
In your case, "IBM" is lost, comp == 7918, and parseInt is called with an argument of "Ayse", leading to the runtime exception.
This is when application trying to convert string to one of the numeric types, but that string does have the appropriate format to convert.
Can you show further "IBM 7918 Ayse Durlanik 7600 Computer"

Categories

Resources