user1808763
user1808763

Reputation: 181

Formatting perfectly with printf in Java

I'm trying to make my program print out a bill of three items with their names quantities and prices. Everything works fine, all I need is how to formate the prices and totals in order to make all the decimals line up everytime, no matter how big the number. Here's my code

    import java.util.Scanner;
    class AssignmentOneTest {

public static void main(String[] args)
{
    Scanner kb = new Scanner(System.in);

    //       System.out.printf("$%4.2f for each %s ", price, item);
    //       System.out.printf("\nThe total is: $%4.2f ", total);

    //process for item one
    System.out.println("Please enter in your first item");
    String item = kb.nextLine();
    System.out.println("Please enter the quantity for this item");
    int quantity = Integer.parseInt(kb.nextLine());
    System.out.println("Please enter in the price of your item");
    double price = Double.parseDouble(kb.nextLine());




    //process for item two
    System.out.println("Please enter in your second item");
    String item2 = kb.nextLine();
    System.out.println("Please enter the quantity for this item");
    int quantity2 = Integer.parseInt(kb.nextLine());
    System.out.print("Please enter in the price of your item");
    double price2 =Double.parseDouble(kb.nextLine());
    double total2 = quantity2*price2;
    //       System.out.printf("$%4.2f for each %s ", price2, item2);
    //       System.out.printf("\nThe total is: $%4.2f ", total2);

    //process for item three
    System.out.println("Please enter in your third item");
    String item3 = kb.nextLine();
    System.out.println("Please enter the quantity for this item");
    int quantity3 = Integer.parseInt(kb.nextLine());
    System.out.println("Please enter in the price of your item");
    double price3 = Double.parseDouble(kb.nextLine());
    double total3 = quantity3*price3;
    //       System.out.printf("$%4.2f for each %s ", price3, item3);
    //       System.out.printf("\nThe total is: $%4.2f ", total3);


    double total = quantity*price;

    double grandTotal = total + total2 + total3;
    double salesTax = grandTotal*(.0625);
    double grandTotalTaxed = grandTotal + salesTax;


    String amount = "Quantity";
    String amount1 = "Price";
    String amount2 = "Total";
    String taxSign = "%";

    System.out.printf("\nYour bill: ");
    System.out.printf("\n\nItem");
    System.out.printf("%28s %11s %11s", "Quantity", "Price", "Total");

    //complete item one format
    System.out.printf("\n%-30s", item);
    System.out.printf("%-10d", (int)quantity);
    System.out.printf("%-10.2f", (float)price);
    System.out.printf("  " + "%-10.2f", (float)total);

    //complete item two format
    System.out.printf("\n%-30s", item2);
    System.out.printf("%-10d", (int)quantity2);
    System.out.printf("%-10.2f", (float)price2);
    System.out.printf("  " + "%-10.2f", (float)total2);

    //complete item three format
    System.out.printf("\n%-30s", item3);
    System.out.printf("%-10d", (int)quantity3);
    System.out.printf("%-10.2f", (float)price3);
    System.out.printf("  " + "%-10.2f", (float)total3);




    System.out.printf("\n\n\nSubtotal %47.2f", grandTotal);
    System.out.printf("\n6.25 %s sales tax %39.2f", taxSign, salesTax);
    System.out.printf("\nTotal %50.2f", grandTotalTaxed);



}

The problem is that every time the prices are the same, everything lines up, but lets say I type in a price of 50.00 and a price of 2.50 for two different items, then the items price and total decimal points don't all line up, please help.

Upvotes: 2

Views: 48709

Answers (2)

Simon
Simon

Reputation: 10841

I find that lining up titles and columns is a lot easier if I do the output in a matched pair of functions, one for the titles and one for the data, e.g.:

public static void prLine (String item, int quantity, double price, double total) {
    System.out.printf("\n%-20.20s %10d %10.2f %10.2f", item, quantity, 
            price, total);
}   

public static void prTitles () {
    System.out.printf("\n%-20s %10s %10s %10s", "Item", "Quantity", 
            "Price", "Total");
}

You can see that it is easy to get the field widths to correspond nicely this way. Then I can use these functions as follows:

prTitles ();
prLine (item,quantity,price,total);
prLine (item2,quantity2,price2,total2);
prLine (item3,quantity3,price3,total3);

... and I get lined-up output in the style I think you're looking for:

Your bill:
Item                   Quantity      Price      Total
first                         1       1.50       1.50
second                       10      12.50     125.00 
third                       456     322.00  146832.00

Putting the output code in functions also greatly reduces the number of lines of code in the main() function.

Upvotes: 8

Mick
Mick

Reputation: 695

You will have to control this yourself.

Basically I'm thinking there's 2 different ways to handle this.

The first way is to check the length of the output before you output it by converting whatever is necessary into a string, then checking it's length. After you do that you can add in spaces in between the prices to make them line up. Something like this may be able to achieve that, of course integrated however you need it:

int length = String.valueOf(1000d).length();

The second way I'm thinking of is adding tabs between the prices to have it auto line up itself. Of course this way you'll have extra spaces most the time between all of the outputs and you'll have to make sure the item name isn't long enough that you'll need 2 tabs, or more.

Good luck! If you need more clarification, please let me know.

EDIT: To make it a bit better, you can incorporate the length checking above and use printf's width specifier to pad in the spaces. It is a bit better.

// calculate padding based on the length of the output
String format = "%" + padding + "d";
System.out.printf(format, variables);

EDIT2: OOP version of this, it isn't perfect but does it very well :)

EDIT3: Added some comments into the code.

http://pastebin.com/CqvAiQSg

Upvotes: 2

Related Questions