如何正确地将CSV文件中的字符串形式的浮点数/双精度数作为浮点数/双精度数导入到程序中?

时间:2018-12-29 20:02:02

标签: java csv parsing format

简介

我制作了一个简单的程序,该程序以.csv文件格式存储数据,随后读取该图进行打印。一切都用Java完成。

csv文件中数据的一个示例是:

2018/12/29
Tejido,321 908,13.55,43.18,$15.98,
Ropa,195 045,20.55,45.93,$123.01,
Gorra de visera,126 561,17.43,42.32,$79.54,
Cerveza,80 109,3.37,17.93,$12.38,
Mercancías de playa,75 065,11.48,39.73,$105.93,
Bebidas alcohólicas,31 215,4.84,27.90,$32.29,
Artículos de cuero,19 098,23.13,44.09,$198.74,

到目前为止我尝试过什么?

在阅读并研究了文档之后,我想到了这种解决方案,该解决方案非常适合我的问题(如果可行的话……)

public class CSVinput {

public static void main(String[] args) throws FileNotFoundException
{
    Scanner scan = new Scanner(new File("produccion.csv"));
    scan.useDelimiter(",");

    while(scan.hasNext())
    {
        String date = scan.next();
        System.out.println(date);
        String name = scan.next();
        System.out.println(name);
        int quantity = Integer.parseInt(scan.next().replaceAll(" ", "."));
        System.out.println(quantity);
        double quality = Double.parseDouble(scan.next());
        System.out.println(quality);
        double realmQ = Double.parseDouble(scan.next());
        System.out.println(realmQ);
        double cost = Double.parseDouble(scan.nextLine());
        System.out.println(cost);

        if (scan.hasNextLine())
        {
            scan.nextLine();
            System.out.println(date+"," + name+"," + quantity+"," + quality+"," + realmQ+"," + cost);
        }
        scan.close();

    }


}
}

问题出在哪里?

问题是当我尝试导入String数据并将其转换为double / float时,然后对我投掷:

Exception in thread "main" java.lang.NumberFormatException: For input 
string: "13.55"

尽管我将其解析为两倍,但足以正确处理。

完全例外错误

Exception in thread "main" java.lang.NumberFormatException: For input string: "13.55"
at 

java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at webscrapper.CSVinput.main(CSVinput.java:29)
C:\Users\Jonathan\Desktop\WebScrapper_03\WebScrapper\nbproject\build- 
impl.xml:1339: The following error occurred while executing this line:
C:\Users\Jonathan\Desktop\WebScrapper_03\WebScrapper\nbproject\build- 
impl.xml:980: Java returned: 1
BUILD FAILED (total time: 1 second)

2 个答案:

答案 0 :(得分:0)

我可以看到三个问题:

  • 您正在尝试解析循环内的一次性行。 请勿这样做,因为这只会使您在重新调试时感到困惑。

    将该代码移到循环的外部

    Scanner scan = new Scanner(new File("produccion.csv"));
    scan.useDelimiter(",");
    String date = scan.nextLine();
    System.out.println(date);
    while(scan.hasNext())
    
  • 修复此问题后,您正在做的事情... 很奇怪 ,字符串为“ 321 908”。

    int quantity = Integer.parseInt(scan.next().replaceAll(" ", "."));
    

    这表示一个字符串,其中的空格用句点替换,并且试图将其解析为整数。现在,这可能取决于您本机使用的thousands separator,但是默认情况下,Java使用美国的逗号约定(“,”)作为千位分隔符,将句点(“。”)作为十进制分隔符。

    由于您的意图不明确,我无法凭经验回答这个问题,但是如果您完全摆脱了空间,那么至少您会得到一个完整的答案...

    int quantity = Integer.parseInt(scan.next().replaceAll(" ", ""));
    
  • 您必须对另一个数字前面的美元符号执行某些操作。您不能使用不是的任何符号来解析双精度数,并且货币也不是数字的一部分。替换它的方式类似于您replaceAll进行数量计算。

答案 1 :(得分:0)

如果您调试了代码,则通过以下一读可以发现:

String date = scan.next();
System.out.println(date);

为可变日期分配了该值:

2018/12/29\r\nTejido

从这一点开始,显然一切都错了。
当然,一个错误是您尝试读取循环中的日期,但这不是造成问题的唯一原因。
为什么使用next()? 您应该使用nextLine()读取文件,并用,分隔每一行:

public static void main(String[] args) {
    Scanner scan = null;
    try {
        scan = new Scanner(new File("produccion.csv"));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    if (scan == null)
        return;

    if (scan.hasNextLine()) {
        String date = scan.nextLine();
        System.out.println(date);
        while (scan.hasNextLine()) {
            String line = scan.nextLine();
            String[] tokens = line.split(",");

            String name = tokens[0];
            System.out.println(name);

            int quantity = Integer.parseInt(tokens[1].replace(" ", ""));
            System.out.println(quantity);

            double quality = Double.parseDouble(tokens[2]);
            System.out.println(quality);
            double realmQ = Double.parseDouble(tokens[3]);
            System.out.println(realmQ);
            double cost = Double.parseDouble(tokens[4].replace("$", ""));
            System.out.println(cost);

            System.out.println(date + "," + name + "," + quantity + "," + quality + "," + realmQ + "," + cost);
        }
        scan.close();
    }
}

从上面的代码中可以看到,需要替换2个:
" """的值,例如"321 908""$"""的值,例如"$15.98"