2009-11-25 71 views
1

我相信这更多的是与我比parseFloat的一部分的任何不符措施的行为的理解,但我承担......的Java parseFloat似乎是不一致的作用

,如果我有输入格式“IDCODE:(3.5)”,其中IDCODE可能是几个不同的预定义字符串,并且保证总是有括号,并且还保证有括号内的数字。

我试图消化所有的输入到IDCODE桶和总值,因此需要抓住括号之间的任何东西,并把它变成一个浮点数,以便我可以总结它

为什么下面不起作用?

Float tot = 0; 
String idCode = ""; 
while(!input.isEmpty()) 
{ 
    idCode = GetIdCode(input); 
    tot = tot + Float.parseFloat(input.substring( 
            input.indexOf("(", input.indexOf(idCode)) + 1, 
            input.indexOf(")", input.indexOf(idCode)))); 
} 

(抛出一个数字格式除外)

在以下没有工作

Float tot = 0; 
String idCode = ""; 
while(!input.isEmpty()) 
{ 
    idCode = GetIdCode(input); 
    String temp = input.substring( 
        input.indexOf("(", input.indexOf(idCode)) + 1, 
        input.indexOf(")", input.indexOf(idCode))); 
    tot = tot + Float.parseFloat(temp); 
} 

这似乎很奇怪,我 - 是什么,我已经被保存到一个临时变量导致的差异?

+2

什么是输入异常时抛出。 – paxdiablo 2009-11-25 06:00:26

+0

为什么这些循环中的任何一个(除非失败)都只是永远循环?你永远不会改变'input',所以如果循环经过一次,它永远不会结束。这表明你已经在每种情况下删除了一些代码,并且你删除的代码可能包含解释为什么一个表单失败并且另一个成功! - ) – 2009-11-25 06:01:39

+0

对不起 - 只是代码的一部分 - 不应该把在那里的结束大括号 - 在这两种情况下输入是相同的 - 这就是为什么我很困惑 – hgh 2009-11-25 06:03:50

回答

4

当你的代码不工作,你认为它应该是,现在是时候进行一些老式的调试了。你会从中得到更多的好处,比这里的一百人的建议,除非建议是做一些很好的老式调试,当然:-)

将您的非工作人员更改为:

while(!input.isEmpty()) 
{ 
    idCode = GetIdCode(input); 

    // New lines below. 
    System.out.println ("input = [" + input + "]"); 
    System.out.println ("idCode = [" + idCode + "]"); 

    int i1 = input.indexOf(idCode); 
    System.out.println ("offst1 = [" + i1 + "]"); 

    int i2 = input.indexOf("(",i1); 
    System.out.println ("offst2 = [" + i2 + "]"); 

    int i3 = input.indexOf(")",i1); 
    System.out.println ("offst3 = [" + i3 + "]"); 

    String s1 = input.substring(i2+1,i3); 
    System.out.println ("strng1 = [" + s1 + "]"); 

    float f1 = Float.parseFloat(s1); 
    System.out.println ("float1 = [" + f1 + "]"); 
    // New lines above. 

    tot = tot + Float.parseFloat(input.substring( 
     input.indexOf("(", input.indexOf(idCode)) + 1, 
     input.indexOf(")", input.indexOf(idCode)))); 

然后让我们知道输出是什么,尽管您很有可能会自己看到问题。

那些println声明应该涵盖每个可以想象的问题,如果它实际上在代码中。

例如,下列项目:

public class xx { 
    public static void main(String args[]) { 
     String idCode = "CT"; 
     String input = "fgdfgdg CT: (2.57)"; 

     System.out.println ("input = [" + input + "]"); 
     System.out.println ("idCode = [" + idCode + "]"); 

     int i1 = input.indexOf(idCode); 
     System.out.println ("offst1 = [" + i1 + "]"); 

     int i2 = input.indexOf("(",i1); 
     System.out.println ("offst2 = [" + i2 + "]"); 

     int i3 = input.indexOf(")",i1); 
     System.out.println ("offst3 = [" + i3 + "]"); 

     String s1 = input.substring(i2+1,i3); 
     System.out.println ("strng1 = [" + s1 + "]"); 

     float f1 = Float.parseFloat(s1); 
     System.out.println ("float1 = [" + f1 + "]"); 

     System.out.println ("full = [" + Float.parseFloat(input.substring( 
      input.indexOf("(", input.indexOf(idCode)) + 1, 
      input.indexOf(")", input.indexOf(idCode)))) + "]"); 
    } 
} 

给我:

input = [fgdfgdg CT: (2.57)] 
idCode = [CT] 
offst1 = [8] 
offst2 = [12] 
offst3 = [17] 
strng1 = [2.57] 
float1 = [2.57] 
full = [2.57] 

特别是,最后一行是印好了我的事实使我相信没有什么错你显示的代码。问题在于别处。

+0

谢谢 - 我认为我需要一个红脸图释 - 我没有当我远程调用它时,知道如何在Java中进行调试...感谢您的耐心建议=) – hgh 2009-11-25 06:54:42

+0

您可以使用jpda进行远程调试,请参阅http://java.sun.com/javase/6/docs/ technotes/guides/jpda/conninv.html(示例)。 – wds 2009-11-25 07:46:00

0

考虑微调/它被解析之前更换前导空格临时,他们也可以触发异常:

tot = tot + Float.parseFloat(temp.trim()); // 

//或

tot = tot + Float.parseFloat(temp.replace(" ","")); 
+0

no - see“temp “是* DOES *工作的那个 - 在任何一种情况下都是相同的子串调用,所以他们大概都有空格或者两者都不是(我可以说他们肯定不会为我的所有输入数据) – hgh 2009-11-25 06:04:54

+0

有你尝试了Float.isNaN(temp)的结果,也许这可以帮助你,但它很奇怪,为什么它不能工作形式临时工 – jerjer 2009-11-25 06:17:56

+0

Float.parseFloat使用Float.valueOf,我认为这会自动调用trim。 – paxdiablo 2009-11-25 06:34:06

1

真正的问题不在于parseFloat。它是用字符串参数调用它,其中包含数字之前和/或之后的字符或空字符串。

问题中没有足够的代码来确切地说明发生了什么,但是如果我试图解决这个问题,我要么使用调试器单步执行代码,要么添加一些System.err.println(...)语句。特别要关注你传递给parseFloat的字符串究竟是什么。

+0

不幸的是,步进不是一个选项 - 我从jasperreports调用函数作为scriptlet(除非有人能告诉我如何逐步调用外部调用的代码),但是,我希望我能! – hgh 2009-11-25 06:44:57

+0

@Georgie - 然后使用'println' – 2009-11-25 06:52:18

0

让你的生活更轻松,而且代码更容易理解,少重复:

Float tot = 0; 

while(!input.isEmpty()) 
{ 
    final String idCode; 
    final int idIndex; 
    final int startIndex; 
    final int endIndex; 
    final String value; 

    idCode  = GetIdCode(input); 
    idIndex = input.indexOf(idCode); 
    startIndex = input.indexOf("(", idIndex) + 1; 
    endIndex = input.indexOf(")", idIndex); 
    value  = input.substring(startIndex, endIndex); 
    tot  = tot + Float.parseFloat(); 
} 

一旦你有每个呼叫分开,你可以很容易地做几件事情: - 检查-1的*指数变量(指示无效输入) - 对任何值(包括值)执行System.out.println,以便您可以轻松查看出了什么问题(我会做System.out.println(“value = \”“+值+“\”“);)

一个好的规则是从不将方法的结果作为方法参数或控制语句传递,它使当事情出错时更难调试。