【问题标题】:java.lang.NumberFormatException: For input string: "1,167.40" [duplicate]java.lang.NumberFormatException:对于输入字符串:“1,167.40”[重复]
【发布时间】:2013-09-16 11:57:36
【问题描述】:

我正在从 CSV 文件中读取数据。其中一个字段包含值1,167.40。读取该字段的代码如下:

String csvFilename = "TEST_FILE.csv";
CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
String[] row = null;
csvReader.readNext(); // to skip the headers
while((row = csvReader.readNext()) != null) 
{
  double val = Double.parseDouble(row[0]); // !!!
}
csvReader.close();

double val = Double.parseDouble(row[0]) 行导致以下错误消息:

java.lang.NumberFormatException:对于输入字符串:“1,167.40”

如何解决这个问题?

附:对于 111.64 等其他值,不会出现此错误。

【问题讨论】:

  • Double.pareseDouble() 不喜欢您提供的字符串中的,。您是否尝试过从输入中删除,?我假设 1,167.40 与 1167.40 相同。
  • 我猜 NumberFormatException 发生的原因是逗号(,)。尝试从 csv 文件中删除它。

标签: java double number-formatting numberformatexception


【解决方案1】:

错误位于输入中间的逗号, 中。一个快速的肮脏解决方案是在将其解析为 double 之前将其删除。

double val = Double.parseDouble(row[0].replaceAll(",", ""));

更好的解决方案是使用NumberFormat 来处理这个问题:

//assumes your server already has English as locale
NumberFormat nf = NumberFormat.getInstance(); /
//...
double val = nf.parse(row).doubleValue();

【讨论】:

  • 替换值实际上是临时解决方案,因为它将变得非常特定于数据内容。弄清楚语言环境并根据它首先格式化数据更有意义。
  • 然后在您的应用程序中附加一个警告“在法国无法使用”;-)
  • @Bathsheba 如果 pc/server 配置为英语默认语言环境,那么没有问题。
  • 对于您的第二个解决方案,编译器会说“无法在原始类型 double 上调用 doubleValue()”
  • @KlausosKlausos 谢谢,代码已修复
【解决方案2】:

您应该使用特定于区域设置的格式:

NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
myNumber = nf.parse(myString);

有些国家交换句号和逗号; (例如 Locale.FRENCH 中的“1.167,40”),所以先去掉逗号是不安全的。

【讨论】:

  • 如何获得双倍价值?
【解决方案3】:

这是因为字符“,”(逗号)。此处的数据代表特定语言环境。所以你应该先使用语言环境信息将数据格式化为十进制,然后再解析。

一个这样的例子是

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class JavaMain {
    public static void main(String[] args) {
        String numberString = "2.105,88";
        //using casting
        try {
            DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.GERMAN);
            df.setParseBigDecimal(true);
            BigDecimal bd = (BigDecimal) df.parseObject(numberString);
            System.out.println(bd.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
        try {
            BigDecimal bd1 = new BigDecimal(nf.parse(numberString).toString());
            System.out.println(bd1.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

【讨论】:

    【解决方案4】:

    Double.parseDouble() 不喜欢您作为参数提供的字符串中的,。您是否尝试过从输入中删除,?我假设 1,167.40 与 1167.40 相同。

    你可以试试:

    double val = Double.parseDouble(row[0].replace(',' , '');
    

    【讨论】:

    • 没有。不。不。永远不要去掉逗号:你会破坏欧洲大陆的语言环境(法国、德国等)。
    • @Bathsheba 这不是这里的主要问题。
    • @Bathsheba 它只是将值传递给 double,无论如何你都必须在没有昏迷的情况下这样做。 replace 返回一个新字符串,所以我认为应该用于语言环境的 row[0] 的原始值没有改变。
    【解决方案5】:

    试试

    NumberFormat.getInstance().parse(row[0]) 而不是Double.parseDouble()

    【讨论】:

      猜你喜欢
      • 2017-09-02
      • 2020-03-11
      • 2015-04-19
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 2013-09-04
      • 1970-01-01
      相关资源
      最近更新 更多