0

Introduction

I made a a simple program that stores data in a .csv file format which later reads to plot. Everything done in Java.

An example from the data from the csv file is:

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,

What I have tried so far?

After reading and research in the docs I came up with this solution which quite adapts to my problem (if it worked...)

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

    
}
}

Where is the problem?

The problem is when I try to import the String data and cast it into double/float which then throws at me:

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

I though that if I parsed it into double it would be more than enough to get it right.

Full Exception Error

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 webscraper.CSVinput.main(CSVinput.java:29)
C:\Users\Jonathan\Desktop\WebScraper_03\WebScraper\nbproject\build- 
impl.xml:1339: The following error occurred while executing this line:
C:\Users\Jonathan\Desktop\WebScraper_03\WebScraper\nbproject\build- 
impl.xml:980: Java returned: 1
BUILD FAILED (total time: 1 second)
Jonalcaide
  • 560
  • 8
  • 21
  • 4
    If you were parsing into a double, you would be right. But you're parsing into an int. – Joe C Dec 29 '18 at 20:04
  • When dealing with Money `float` and `double` are really bad choices because they have *digitization errors*: `0.1` in binary is an *endless fraction* which cannot be stored in a computer using fix digit binary numbers. – Timothy Truckle Dec 29 '18 at 20:09
  • 2
    Which line throws the exception? Also, locale could be a problem, as I believe Java takes this into account when performing the function. – KellyM Dec 29 '18 at 20:11

2 Answers2

0

There are three problems that I can see:

  • You are attempting to parse a one-off line inside of your loop. Don't do that as that'll only serve to confuse you when you go back to debug this.

    Move that code to the outside of the loop.

    Scanner scan = new Scanner(new File("produccion.csv"));
    scan.useDelimiter(",");
    String date = scan.nextLine();
    System.out.println(date);
    while(scan.hasNext())
    
  • After you fix that, you're doing something...weird with the string "321 908".

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

    This represents a string which has spaces replaced with periods, and is attempted to be parsed as an integer. Now this may depend on what thousands separator you use natively, but by default Java uses the United States convention of comma (",") as thousands separator and period (".") as decimal separator.

    I can't answer this empirically since your intention isn't clear, but at a minimum if you got rid of the space altogether, you'd get an int...

    int quantity = Integer.parseInt(scan.next().replaceAll(" ", ""));
    
  • You'll have to do something about that dollar sign in front of another number. You can't parse a double with any symbol that isn't a double, and currency isn't a part of a numeral. Replace it similar to how you do the replaceAll for quantity.

Makoto
  • 104,088
  • 27
  • 192
  • 230
  • I wanted an int. I was trying to see if it was a space or something fearing that I wound't be able to use it as integer. Thanks for the info! Merry X-mas and happy new year! – Jonalcaide Dec 29 '18 at 21:32
0

If you debugged the code you would find out that by this 1st reading:

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

the variable dates is assigned this value:

2018/12/29\r\nTejido

From this point on, everything is wrong obviously.
Of course one mistake is that you try to read the date inside the loop, but this is not the only reason of your problems.
Why do you use next()? You should read the file using nextLine() and split each line by ,:

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

As you can see from the code above, there are 2 replacements needed:
The " " to "" for values like "321 908" and the "$" to "" for values like "$15.98"

forpas
  • 160,666
  • 10
  • 38
  • 76
  • 1
    Using `next` is fine to read individual tokens on the line, which is what the OP is doing. It's more arcane than using `split` but it works. – Makoto Dec 29 '18 at 20:47
  • The only flaw I see here is that the array gets out of index. There rest is all I wanted. Great answer and thank you for your time. Merry X-mas and happy new year! – Jonalcaide Dec 29 '18 at 20:48
  • @forpas: The OP explicitly set the delimiter to ",", which is why it worked. – Makoto Dec 29 '18 at 20:49
  • @WhiteGlove The array can get out of index only if each line does not contain the number of items as in your sample. So you may want to check it. – forpas Dec 29 '18 at 20:50
  • @forpas: **I did.** That's what I based *my* answer on. Please don't presume to lecture me; I'm merely pointing out an observation I made on this. Your code would work too but it's adding unnecessary ceremony to something which already mostly works. – Makoto Dec 29 '18 at 20:54
  • *mostly works* you're joking right? You pointed at least 3 needed changes and I pointed at least 2 more. Flaws in logic and coding. What more do you need to propose a better and safer solution? And don't lecture me too. Now stop it because the comments section is not the place to argue. – forpas Dec 29 '18 at 20:57
  • Please Makoto and @forpas, this is not an arena fight. We are all learning here from different points of view. I made a solution from both answers and I thank you all. – Jonalcaide Dec 30 '18 at 17:00