Reading from a txt file in Java - java

I'm taking a C course right now, but I also want to practice my work in Java as well. I'm having trouble reading from a file in Java (I want to get different types (double, int, etc..) from a file and store it in some variables. I know in C, the code would be like this:
int main(void) {
FILE* fp;
char name[29];
int qty;
char item[20];
float price;
fp= fopen("input.txt","r");
if (fp == NULL) {
printf("Couldn't open the file.");
return;
}
while (fscanf(fp, "%s %d %s %.2f\n", name, &qty, item, &price) != NULL) {
// do something
}
return 0;
}
But what about in Java? I have done this so far but it doesn't work. I did get an output but the format wasn't what I wanted.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main_Class {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = null;
try {
scan = new Scanner(new File("input.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (scan.hasNextLine()) {
String name = "";
int quantity = 0;
String item_name = "";
double price = 0.0;
if(scan.hasNext()) {
name = scan.next();
}
if(scan.hasNextInt()) {
quantity = scan.nextInt();
}
if(scan.hasNext()) {
item_name = scan.next();
}
if(scan.hasNextDouble()) {
price = scan.nextDouble();
}
System.out.println(name + " " + quantity + " " + item_name + " " + price);
}
}
}
EDIT: Sorry guys, I forgot to include the txt file contents. I want my output just to be like this.
Smith 3 Sweater $22.50
Reich 3 Umbrella $12.50
Smith 1 Microwave $230.00
Lazlo 1 Mirror $60.00
Flintstone 5 Plate $10.00
Lazlo 1 Fridge $1200.00
Stevenson 2 Chair $350.00
Smith 10 Candle $3.50
Stevenson 1 Table $500.00
Flintstone 5 Bowl $7.00
Stevenson 2 Clock $30.00
Lazlo 3 Vase $40.00
Stevenson 1 Couch $800.00
My output (In Java, and I'm just going to include some of them since they are quite long):
Smith 3 Sweater 0.0
$22.50 0 Reich 3.0
Umbrella 0 $12.50 0.0
Smith 1 Microwave 0.0
$230.00 0 Lazlo 1.0
Mirror 0 $60.00 0.0
Flintstone 5 Plate 0.0
$10.00 0 Lazlo 1.0

if(scan.hasNextDouble())
{
price = scan.nextDouble();
}
change this to
price = Double.parseDouble(scan.next().substring(1));
And change
System.out.println(name + " " + quantity + " " + item_name + " " + price);
this to
System.out.println(name + " " + quantity + " " + item_name + " $" + price);

If all you care about is printing the data, you might as well read everything as a string and simplify the code to:
while (scan.hasNextLine()) {
String name, quantity, item_name, price;
if(scan.hasNext()) {
name = scan.next();
}
else ...
if(scan.hasNext()) {
quantity = scan.nextInt();
}
else ...
if(scan.hasNext()) {
item_name = scan.next();
}
else ...
if(scan.hasNext()) {
price = scan.nextDouble();
}
else ...
System.out.println(name + "\t" + quantity + "\t" + item_name + "t" + price);
}
The tab character, '\t', makes the output look a little better. Where the else's are, you can set default values in case nothing is found.
If you actually care if something is an int or a double, you can just use the parse methods, i.e.
int int_quantity = Integer.parseInt( quantity );

Related

While loop overwriting other inputs

Whenever I put inputs into this loop, no matter how many it will only write my final input to the file
Here's the code:
import java.util.Scanner;
import java.io.IOException;
import java.io.*;
class lista {
public static void main(String[] args) throws IOException {
Scanner n = new Scanner(System.in);
int x = 0;
File productList = new File("productList.txt");
FileWriter fr = new FileWriter("productList.txt", true);
/// While Loop Start
while (x == 0) {
System.out.println("Enter the product:");
String product = n.nextLine();
System.out.println("");
System.out.println("Enter the price:");
String price = n.nextLine();
System.out.println("");
System.out.println("Enter the type of product, e.g. Movie, Bluray, etc...");
String type = n.nextLine();
System.out.println("");
System.out.println(product + " - " + "$" + price + " (" + type + ")" + "\n\n");
try {
fr.write((product + " - " + "$" + price + " (" + type + ")" + "\n\n"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Type \"0\" if you would like to stop, type \"1\" if you would like to continue.");
int y = n.nextInt();
n.nextLine();
if (y == 1) {
x = 0;
} else {
x = 1;
fr.close();
}
}
/// While Loop Ends
}
}
I can input something like,
1,1,1,1
2,2,2,1
3,3,3,0
, and it will only print:
3 - $3 (3)
Thanks.
This is a possible duplicate of Trouble with filewriter overwriting files instead of appending to the end.
However you seem to have found the solution yourself already (the true parameter when creating the FileWriter). This should append to the file instead of overwriting it. If this does not work, then you might have a problem with the file or the OS. In any case, your code is not fundamentally wrong and should work.
Some suggestions for readability and ease of use on the code itself (just minor details).
Scanner in = new Scanner(System.in);
PrintStream out = System.out;
try (FileWriter writer = new FileWriter("productList.txt", true)) {
INPUT_LOOP:
while (true) {
out.println("Enter the product:");
String product = in.nextLine();
out.println();
out.println("Enter the price:");
String price = in.nextLine();
out.println();
out.println("Enter the type of product, e.g. Movie, Bluray, etc...");
String type = in.nextLine();
out.println();
String entry = product + " - " + "$" + price + " (" + type + ")" + "\n\n";
out.println(entry);
writer.append(entry);
out.println("Type \"exit\" if you would like to stop, any other input will continue.");
if (in.nextLine().trim().toLowerCase().equals("exit")) {
break INPUT_LOOP;
}
}
} catch (IOException e) {
e.printStackTrace();
}

parse text file delimited by | operator and retain the header column name

I have an text file in which the fields are separated by | operator. First line in the txt file holds the column Names. I am able to parse and split the fields based on | operator using Scanner but i need the header column name for each field value
Please find my sample text file content which needs to be parsed below:
FirstName||lastName||Age||Salary
Kong||King||20||$1000
Steve||Rogers|| ||$2000
Mark||Richer||30||$12000
Spencer||Cook||31||$700
Result which i get now:
FirstName
lastName
Age
Salary
Kong
King
20
$1000
Steve
Rogers
$2000
Mark
Richer
30
$12000
Spencer
Cook
31
$700
sample code which i used:
FileInputStream inputStream = new FileInputStream("c:\\sample\\sample.txt");
Scanner scanner = new Scanner(inputStream, "UTF-8");
scanner.useDelimiter("[\\||]");
while(scanner.hasNext()){
System.out.println(scanner.next().trim());
}
scanner.close();
}
Result which i need is like below:
FirstName -> Kong
lastName -> King
Age -> 20
Salary -> $1000
FirstName -> Steve
lastName -> Rogers
Age ->
Salary -> $2000
Any Help is appreciated..
Don't know if it is the most efficient solution but managed it like this, hope it helps! :) The file path is different because I am in Linux.
FileInputStream inputStream = new FileInputStream("/home/dzandes/Music/test.txt");
Scanner scanner = new Scanner(inputStream, "UTF-8");
scanner.useDelimiter("[\\||]");
List<String> contents = new ArrayList<>();
while (scanner.hasNext()) {
String s = scanner.next().trim();
// First, we split the Strings with new line in between
if (!s.isEmpty()) {
if (s.contains("\n")) {
String[] s_ = s.split("\n");
for (String str : s_) {
contents.add(str);
}
} else {
contents.add(s);
}
} else {
contents.add(s);
}
}
scanner.close();
// Then we keep the necessary empty Strings we need, e.g. Steve Roger's age, and skip the rest
List<String> contents_ = new ArrayList<>();
for (int j = 0; j < contents.size(); j++) {
if (!contents.get(j).isEmpty()) {
contents_.add(contents.get(j));
} else {
if (contents.get(j+1).isEmpty()
&& contents.get(j-1).isEmpty()) {
contents_.add(contents.get(j));
}
}
}
/**
* Just left this for-loop to see what the list contains after the above
*
* Of course, you can comment it
*/
for (String s : contents_) {
System.out.println("s :" + s);
}
int i = 1;
while (i*4 < contents_.size()) {
System.out.println(contents_.get(0) + " - " + contents_.get(i*4));
System.out.println(contents_.get(1) + " - " + contents_.get((i*4) + 1));
System.out.println(contents_.get(2) + " - " + contents_.get((i*4) + 2));
System.out.println(contents_.get(3) + " - " + contents_.get((i*4) + 3));
i++;
}
It prints,
FirstName - Kong
lastName - King
Age - 20
Salary - $1000
FirstName - Steve
lastName - Rogers
Age -
Salary - $2000
FirstName - Mark
lastName - Richer
Age - 30
Salary - $12000
FirstName - Spencer
lastName - Cook
Age - 31
Salary - $700

Trying to understand why I can't round to 2 decimal places in one code but can in another thats virtually the same

I am writing a few java classes for a uni assignment and am having some trouble understanding what is going behind the scenes when I am trying to round to 2 decimal places. I have searched around but can't seem to find an answer that solves this particular version of the problem. So my code asks users to input prices into a cash register program and then prints the total price as well as the number of items. The total price has to be stored as an integer value (i.e 3.21 would be 321) but then outputted as a decimal value at the end. Here's my code:
public class CashRegister_Re_Implementation {
private double totalPrice;
private int itemCount;
CashRegister_Re_Implementation() {
totalPrice = 0;
itemCount = 0;
}
public double getTotal() {
String roundOff = String.format("%.2f", ((totalPrice * 100) / 10000));
double newDecimal;
newDecimal = Double.parseDouble(roundOff);
return newDecimal;
}
public int getItemCount() {
return itemCount;
}
public void addItem(double price) {
totalPrice += price * 100;
itemCount++;
}
}
class CashRegisterTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
CashRegister_Re_Implementation reg1 = new CashRegister_Re_Implementation();
int count1 = 0;
System.out.println("Register 1 (2 items)");
while (count1 < 2) {
System.out.print("Item price: £");
double price = scan.nextDouble();
reg1.addItem(price);
count1++;
}
CashRegister_Re_Implementation reg2 = new CashRegister_Re_Implementation();
int count2 = 0;
System.out.println("\nRegister 2 (2 items)");
while (count2 < 2) {
System.out.print("Item price: £");
double price = scan.nextDouble();
reg2.addItem(price);
count2++;
}
CashRegister_Re_Implementation reg3 = new CashRegister_Re_Implementation();
int count3 = 0;
System.out.println("\nRegister 2 (2 items)");
while (count3 < 2) {
System.out.print("Item price: £");
double price = scan.nextDouble();
reg3.addItem(price);
count3++;
}
System.out.println("\nFirst register. Total price: £" + reg1.getTotal() + "p for " + reg1.getItemCount() + " items");
System.out.println("Second register. Total price: £" + reg2.getTotal() + "p for " + reg2.getItemCount() + " items");
System.out.println("Third register. Total price: £" + reg3.getTotal() + "p for " + reg3.getItemCount() + " items");
}
}
It works fine except that if I enter all 1.00 I get this output:
Register 1 (2 items)
Item price: £1.00
Item price: £1.00
Register 2 (2 items)
Item price: £1.00
Item price: £1.00
Register 2 (2 items)
Item price: £1.00
Item price: £1.00
First register Total price: £2.0p for 2 items
Second register Total price: £2.0p for 2 items
Third register Total price: £2.0p for 2 items
Why am I getting £2.0 instead of £2.00?
I wrote this separately and it works absolutely fine:
public static void main(String[] args) {
double x = 100;
double y = 100;
double z = x + y;
String roundOff = String.format("%.2f", z);
System.out.println(roundOff);
}
Output:
200.00
Process finished with exit code 0
Why can't I get £2.00 in the exercise? Many thanks for any time taken to read all this :p
This is because your method getTotal has a return type of double but while concatenating the value in System.out.println you don't use formatting.
public double getTotal() {
String roundOff = String.format("%.2f", ((totalPrice * 100) / 10000));
double newDecimal;
newDecimal = Double.parseDouble(roundOff);
return newDecimal;
}
You should either return the formatted string from above method or change the print statements as follows:
System.out.println("\nFirst register. Total price: £" + String.format("%.2f", ((reg1.getTotal() * 100) / 10000)) + "p for " + reg1.getItemCount() + " items");
System.out.println("Second register. Total price: £" + String.format("%.2f", ((reg2.getTotal() * 100) / 10000)) + "p for " + reg2.getItemCount() + " items");
System.out.println("Third register. Total price: £" + String.format("%.2f", ((reg3.getTotal() * 100) / 10000)) + "p for " + reg3.getItemCount() + " items");
Note that a formatter has now been applied to the return value that you get from the method getTotal().
For a better reusability you should outline the first line in the method getTotal() in a new method like getTotalFormatted(). So you can use it in your rounding-algorithm and for printing too.

java: How Not to save values from the code when looping back again?

How do I not store values from the program when it loops back again. For example, if I plan to enter two families, first I will ask for the details of the first family and display their names, and then I want to use the same variables to collect the next family and display their names without having stored information from the previous family.
public static void main(String[] args) {
// TODO code application logic here
String ans;
String res;
double cont;
int cot;
String name;
String order = "";
do {
ans = JOptionPane.showInputDialog(null,"What is the name of the "
+ "family?" );
res = JOptionPane.showInputDialog(null, "How many member in the " + ans +
" family?");
cot = Integer.parseInt(res); // Converts res String to a number
for (int count = 1; count < cot; count ++) {
name = JOptionPane.showInputDialog(null, " Enter first name: " + count);
order += name + " " + ans + "\n";
}
JOptionPane.showMessageDialog(null, "Members of the " + ans
+ " Family" + "\n" + order);
cont = JOptionPane.showConfirmDialog(null, "Do you want to add another "
+ "family", "Membership", JOptionPane.YES_NO_OPTION);
}while (cont == JOptionPane.YES_OPTION);
if (cont == JOptionPane.NO_OPTION){
JOptionPane.showMessageDialog(null," Come Back Again");
}
}
}
Your order variable is a String that you are adding the names to. Just reset it at the beginning of the loop:
...
do {
order = "";
...

Looping program back to ''menu''

I just writed this program, it is to train myself for the upcomming exam this monday.
A thing i would like to add is: after a user is done with one of the exchange options 1/2/3 i would like to give the option to let the user return to the beginning welcome to the money exchange! etc.....
i have tried some a for loop and a while loop but i couldn't get it to work.
Would be cool if after the money exchange process that the user get the option to return to the beginning by typing y or n is this possible?
/* This program is written as a excercise to prep myself for exams.
* In this program the user can:
* 1. Select a currency (other than euro's)
* 2. Input the amount of money
* 3. transfer the amount of currency to euro's
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println(" Welcome to the money exchange! \n Please pick one of the currencies by useing 1 / 2 / 3 \n \n 1 = US dollar \n 2 = GB pounds \n 3 = Yen \n ");
System.out.print("Input : ");
DecimalFormat df = new DecimalFormat() ;
df.setMaximumFractionDigits(2);
int choice = input.nextInt() ;
double transfee = 2.41 ;
double USrate = 0.9083 ;
double GBrate = 1.4015 ;
double YENrate = 0.0075 ;
if (choice > 3 || choice < 1) {
System.out.println("Invalid input!...... Please try agian\n");
} else {
if(choice == 1) {
System.out.println("You have choosen for US dollar \n");
System.out.print("Please enter amount US dollar: ");
double USamount = input.nextDouble() ;
double deuros = USamount * USrate ;
double ddisburse = deuros - transfee ;
System.out.print("\nInput amount US dollar:. " + USamount + "\n");
System.out.print("Worth in euro's:........ " + df.format(deuros) + "\n");
System.out.print("Transfer cost:.......... " + transfee + "\n");
System.out.print("Amount to disburse:..... " + df.format(ddisburse) + "\n" );
}else {
if(choice == 2){
System.out.println("You have choosen for GB pounds");
System.out.print("Please enter amount GB ponds: ");
double GBamount = input.nextDouble();
double geuros = GBamount * GBrate ;
double gdisburse = geuros - transfee;
System.out.print("\nInput amount GB pound:. " + GBamount + "\n");
System.out.print("Worth in euro's........ " + df.format(geuros) + "\n");
System.out.print("Transfer cost:......... " + transfee + "\n");
System.out.print("Amount to disburse:.... " + df.format(gdisburse) + "\n");
}else {
if(choice == 3){
System.out.println("You have choosen for Yen");
System.out.print("Please enter amount Yen: ");
double YENamount = input.nextDouble();
double yeuros = YENamount * YENrate ;
double ydisburse = yeuros - transfee ;
System.out.print("\nInput amount Yen:... " + YENamount + "\n");
System.out.print("Worth in euro's..... " + df.format(yeuros) + "\n");
System.out.print("Transfer cost:...... " + transfee + "\n");
System.out.print("Amount to disburse:. " + df.format(ydisburse) + "\n");
}
}
}
}
}
}
You could wrap your program with a while loop, which checks if the user entered 'y' at the end like this:
import java.text.DecimalFormat;
import java.util.Scanner;
class YourClassName
{
public static void main(String[] args)
{
boolean askAgain = true;
while (askAgain)
{
Scanner input = new Scanner(System.in);
System.out.println(
" Welcome to the money exchange! \n Please pick one of the currencies by useing 1 / 2 / 3 \n \n 1 = US dollar \n 2 = GB pounds \n 3 = Yen \n ");
System.out.print("Input : ");
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
int choice = input.nextInt();
double transfee = 2.41;
double USrate = 0.9083;
double GBrate = 1.4015;
double YENrate = 0.0075;
if (choice > 3 || choice < 1)
{
System.out.println("Invalid input!...... Please try agian\n");
} else
{
if (choice == 1)
{
System.out.println("You have choosen for US dollar \n");
System.out.print("Please enter amount US dollar: ");
double USamount = input.nextDouble();
double deuros = USamount * USrate;
double ddisburse = deuros - transfee;
System.out.print(
"\nInput amount US dollar:. " + USamount + "\n");
System.out.print("Worth in euro's:........ "
+ df.format(deuros) + "\n");
System.out.print(
"Transfer cost:.......... " + transfee + "\n");
System.out.print("Amount to disburse:..... "
+ df.format(ddisburse) + "\n");
} else
{
if (choice == 2)
{
System.out.println("You have choosen for GB pounds");
System.out.print("Please enter amount GB ponds: ");
double GBamount = input.nextDouble();
double geuros = GBamount * GBrate;
double gdisburse = geuros - transfee;
System.out.print(
"\nInput amount GB pound:. " + GBamount + "\n");
System.out.print("Worth in euro's........ "
+ df.format(geuros) + "\n");
System.out.print(
"Transfer cost:......... " + transfee + "\n");
System.out.print("Amount to disburse:.... "
+ df.format(gdisburse) + "\n");
} else
{
if (choice == 3)
{
System.out.println("You have choosen for Yen");
System.out.print("Please enter amount Yen: ");
double YENamount = input.nextDouble();
double yeuros = YENamount * YENrate;
double ydisburse = yeuros - transfee;
System.out.print("\nInput amount Yen:... "
+ YENamount + "\n");
System.out.print("Worth in euro's..... "
+ df.format(yeuros) + "\n");
System.out.print(
"Transfer cost:...... " + transfee + "\n");
System.out.print("Amount to disburse:. "
+ df.format(ydisburse) + "\n");
}
}
}
}
System.out.println("Do you want to do another calculation? (y/n)");
String againAnswer = input.next();
askAgain = againAnswer.equalsIgnoreCase("y");
}
}
}
Setting the boolean variable to true first lets you enter the loop. The user will be asked as long as he types an y at the end. Every other character would exit the loop:
String againAnswer = input.next();
askAgain = againAnswer.equalsIgnoreCase("y");
You could also check for explicit n, but that is up to you.
Put the code inside a while loop (while(true)). At the end of each if block
add one nested if.
System.out.print(Do you want to continue?");
if(in.next().equals("Y")) {
continue;
}
And you have add one extra menu(4th) for exit :
if(choice == 4){
break;
}

Categories