字符串格式与货币
问题描述:
我想写一个程序,收到一个输入和输出文件的硬币列表和这些硬币的金额。字符串格式与货币
import java.io.*;
import java.util.*;
public class CookieJar {
public static void cashingIn(File input, File output){
try{
Scanner in = new Scanner(input);
PrintWriter writ = new PrintWriter(output);
double sum = 0;
if(in.hasNext()){
String next = in.nextLine();
Scanner help = new Scanner(next);
while(in.hasNextLine()){
int y = Integer.parseInt(next.substring(0, 1));
if(next.contains("pennies")){
sum += y*0.01;
}
if(next.contains("dimes")){
sum += y*.1;
}
if(next.contains("quarters")){
sum += y*.25;
}
if(next.contains("nickles")){
sum += y*.05;
}
if(next.contains("penny")){
sum += .01;
}
if(next.contains("dime")){
sum += .1;
}
if(next.contains("nickle")){
sum += .05;
}
if(next.contains("quarter")){
sum += .25;
}
if(sum == 0){
String find = String.format("%s", "You have no money in the jar");
writ.println(find);
}
String fixer = String.format("$%sf", sum);
writ.println("You have " + fixer + " in the jar");
}
help.close();
}
else{
String find = String.format("%s" , "You have no money in the jar");
writ.println(find);
}
in.close();
writ.close();
}catch(IOException e){
}
}
}
我用这段代码遇到的问题是我无法从文件中获取硬币的数量,并确定它是什么类型的硬币。这是我正在使用的测试器方法的一个示例。
@Test
public void test3() {
try {
// create file
File input = folder.newFile("input.txt");
File output = folder.newFile("output.txt");
PrintWriter write = new PrintWriter(input);
write.println("32 nickels");
write.println(" 1");
write.println(" nickel 42");
write.println("quarters 1 penny");
write.println("1 quarter 23 pennies 16");
write.println("");
write.println("dimes 1 dime 1 dime 1 dime 1 dime");
write.close();
// invoke program
CookieJar.cashingIn(input, output);
// verify file results
assertTrue ("Output file does not exist", output.exists());
Scanner scan = new Scanner(output);
String expected = "You have $14.64 in the jar";
assertTrue ("Unexpected end of file: expected \"%s\"" + expected, scan.hasNext());
String actual = scan.nextLine();
assertEquals("Incorrect result", expected, actual);
assertFalse ("File contains more data than expected", scan.hasNext());
scan.close();
}
catch (IOException e) {
fail("No exception should be thrown");
}
}
我也必须让这个数字有逗号,如果我进入数千。我可能没有足够的具体知识来帮助我,所以如果你需要更多的澄清,请问。谢谢你的任何帮助。我对形式化很困惑。
答
这是一种扩展的评论,但接下来会帮助你自己解决问题,我相信。
这很好,你有一个测试,但它和代码测试/做得太多。处理字符串和计数硬币至少是一项责任,与文件交互绝对是其他责任。通过一次测试,您的测试将变得复杂而且缓慢。
运用Single Responsibility Principle使得它更容易和更快的测试:
//The ONLY responsibility of this class is to keep count of coin strings it is given
public class CookieJar {
private double sum = 0; //consider internally counting pennies with an int
public void addString(string next){
int y = Integer.parseInt(next.substring(0, 1));
if(next.contains("pennies")){
sum += y*0.01;
}
//etc (but no code that reads/writes to console or files)
}
public string summarize(){
if(sum == 0){
return String.format("%s", "You have no money in the jar");
}
String fixer = String.format("$%sf", sum);
return "You have " + fixer + " in the jar";
}
}
测试将容易得多写快,你可以很容易地在不同的测试单独测试每个硬币类型,然后测试所有在一起的时候,他们所有的工作:
@Test
public void test3() {
CookieJar cookieJar = new CookieJar();
cookieJar.addString("32 nickels");
assertEquals("You have $1.60 in the jar", cookieJar.summarize());
}
的从文件代码现在看起来简单:
//The ONLY responsibility of this class is to allow reading and writing of coin files
public final class CookieJarIo {
private CookieJarIo(){} //static class
public static void cashingIn(File input, File output){
try{
Scanner in = new Scanner(input);
PrintWriter writ = new PrintWriter(output);
CookieJar cookieJar = new CookieJar(); //use our other class
if (in.hasNext()){
String next = in.nextLine();
Scanner help = new Scanner(next);
while(in.hasNextLine()){
cookieJar.addString(next);
writ.println(cookieJar.summarize());
}
help.close();
} else {
writ.println(cookieJar.summarize());
}
in.close();
writ.close();
} catch(IOException e){
}
}
}
答
您应该认真考虑@ weston关于职责分离的回答。
但是,在此代码中,如果您注意到您希望输入文件包含交替整数和字符串的流(例如,
32 nickels
1
nickel 42
quarters 1 penny
1 quarter 23 pennies 16
dimes 1 dime 1 dime 1 dime 1 dime
您可以检测并在此模式与Scanner in
进程令牌:
int amountInPennies = 0;
while (in.hasNextInt()) {
int quantity = in.nextInt();
if (!in.hasNext()) {
System.err.println("Didn't have a unit! Stopping.");
break;
}
String unit = in.next();
switch (unit) {
case "penny":
case "pennies":
amountInPennies += 1 * quantity;
break;
case "nickel":
case "nickels":
amountInPennies += 5 * quantity;
break;
// etc.
}
}
BigDecimal amountInDollars = BigDecimal.valueOf(amountInPennies, -2);
System.out.println("You have " + amount + " in the jar.");
在如何格式化量作为货币计算,你应该看看NumberFormat.getCurrencyInstance()
不要使用一个'double'代表金钱,它不能完全代表所有的值(例如,'0.1'不能被表示)。改用'BigDecimal'。 – Keppil
“我用这段代码遇到的问题是,我很难得到”也许你可能更具体?问题可能是您使用的是奇怪的子字符串 –
包含“宿舍”的行也包含“季度”,因此您将对所有金额进行重复计算(除了一分钱) –