使用Java中的printf完美格式化

我正在努力让我的程序打印出三个项目的清单,其中包含名称数量和价格。 一切正常,我需要的是如何合成价格和总数,以便每次都能排列所有小数,无论数字有多大。 这是我的代码

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); } 

问题是,每次价格相同,一切都排好,但是我可以说我输入了50.00的价格和两个不同商品的价格2.50,那么商品价格和小数点总数并不排列, 请帮忙。

我发现,如果我在一对匹配的函数中输出,标题和列的排列更容易,一个用于标题,一个用于数据,例如:

 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"); } 

您可以看到很容易通过这种方式使字段宽度很好地对应。 然后我可以使用这些函数如下:

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

…我认为你正在寻找的风格是排队的输出:

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

将输出代码放在函数中也大大减少了main()函数中的代码行数。

你必须自己控制它。

基本上我认为有两种不同的方法可以解决这个问题。

第一种方法是在输出之前检查输出的长度,方法是将必要的东西转换成字符串,然后检查它的长度。 执行此操作后,您可以在价格之间添加空格以使它们对齐。 这样的东西可能能够实现这一点,当然集成但是你需要它:

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

我想到的第二种方法是在价格之间添加标签,让它自动排队。 当然,通过这种方式,您可以在所有输出之间获得额外的空间,并且您必须确保项目名称不够长,以至于您需要2个或更多标签。

祝你好运! 如果您需要更多说明,请告诉我。

编辑:为了使它更好一点,你可以结合上面的长度检查,并使用printf的宽度说明符填充空格。 它好一点。

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

EDIT2:这个的OOP版本,它不是很完美,但它做得很好:)

EDIT3:在代码中添加了一些注释。

http://pastebin.com/CqvAiQSg