2016-03-18 99 views
1

我想写一个程序,收到一个输入和输出文件的硬币列表和这些硬币的金额。字符串格式与货币

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

我也必须让这个数字有逗号,如果我进入数千。我可能没有足够的具体知识来帮助我,所以如果你需要更多的澄清,请问。谢谢你的任何帮助。我对形式化很困惑。

+2

不要使用一个'double'代表金钱,它不能完全代表所有的值(例如,'0.1'不能被表示)。改用'BigDecimal'。 – Keppil

+0

“我用这段代码遇到的问题是,我很难得到”也许你可能更具体?问题可能是您使用的是奇怪的子字符串 –

+1

包含“宿舍”的行也包含“季度”,因此您将对所有金额进行重复计算(除了一分钱) –

回答

1

这是一种扩展的评论,但接下来会帮助你自己解决问题,我相信。

这很好,你有一个测试,但它和代码测试/做得太多。处理字符串和计数硬币至少是一项责任,与文件交互绝对是其他责任。通过一次测试,您的测试将变得复杂而且缓慢。

运用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){ 

     } 
    } 
} 
0

您应该认真考虑@ 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()