1

My task is to read values from a csv file, and import each line of information from this file into an object array. I think my issue is the blank data elements in my csv file which doesn't work for my parsing from string to int, but I have found no way to deal with this. Here is my code:

`fileStream = new FileInputStream(pFileName);
        rdr = new InputStreamReader(fileStream);
        bufRdr = new BufferedReader(rdr);
        lineNum = 0;`    

        while (line != null) {
            lineNum++;
            String[] Values = new String[13];
            Values = line.split(",");
            
            
            int cumulPos = Integer.parseInt(Values[6]);
            int cumulDec = Integer.parseInt(Values[7]);
            int cumuRec = Integer.parseInt(Values[8]);
            int curPos = Integer.parseInt(Values[9]);
            int hosp = Integer.parseInt(Values[10]);
            int intenCar = Integer.parseInt(Values[11]);
            double latitude = Double.parseDouble(Values[4]);
            double longitude = Double.parseDouble(Values[5]);

            covidrecordArray[lineNum] = new CovidRecord(Values[0], cumulPos, cumulDec, cumuRec, curPos, hosp,
                    intenCar, new Country(Values[1], Values[2], Values[3], Values[13], latitude, longitude));

If anyone could help it would be greatly appreciated.

Clamont04
  • 11
  • 3
  • 1
    This does not look right. You do `while (line != null)` then without any processing you overwrite `line` with `line = bufRdr.readLine();` – Scary Wombat May 23 '22 at 02:28
  • 1
    Also I recommend that you use a proper csv library – Scary Wombat May 23 '22 at 02:29
  • I have removed the repeated bufRdr.readLine(); but I now get a NumberFormatException for my CumulativePositive entry (one of my objects parameters) saying there is still an error with my parsing. Any clue why? – Clamont04 May 23 '22 at 03:03
  • 1
    For a start change to `String[] Values = line.split(",");` - next inspect the values (maybe a blank line) and also check that that the length of the `Values` is is as expected. – Scary Wombat May 23 '22 at 04:01

2 Answers2

1

As already suggested, use a proper CSV Parser if you can but if for some unknown reason you can't, this could be one way you can do it. Be sure to read the comments in code:

fileStream = new FileInputStream(pFileName);
rdr = new InputStreamReader(fileStream);
bufRdr = new BufferedReader(rdr);

// Remove the following line if there is no Header line in the CSV file.
String line = bufRdr.readLine();
    
String csvFileDataDelimiter = ",";
List<CovidRecord> recordsList = new ArrayList<>();
    
// True value calculated later in code (read comments).
int expectedNumberOfElements = 0;  // 0 is default
    
while ((line = bufRdr.readLine()) != null) {
    line = line.trim();
    // If for some crazy reason a blank line is encountered...skip it.
    if (line.isEmpty()) {
        continue;
    }

    /* Get the expected number of elements within each CSV File Data Line.
       This is based off of the number of actual delimiters within a file 
       data line plus 1. This is only calculated from the very first data 
       line.                                                            */
    if (expectedNumberOfElements == 0) {
         expectedNumberOfElements = line.replaceAll("[^\\" + csvFileDataDelimiter + "]", "").length() + 1;
    }
        
    /* Create and fill (with Null String) an array to be the expected 
       size of a CSV data line. This is done because if a data line 
       contains nothing for the last data element on that line then 
       when the line is split, the srray that is created will be short 
       by one element. This will ensure that there will alsways be a 
       Null String ("") present within the array when there is nothing 
       in the CSV data line. This null string is used in data validations
       so as to provide a default value (like 0) if an Array Element
       contains an actual Null String ("").                           */
    String[] csvLineElements = new String[expectedNumberOfElements];
    Arrays.fill(csvLineElements, "");
    
    /* Take the array from the split (values) and place the data into
       the csvLineElements[] array.             */
    String[] values = line.split("\\s*,\\s*"); // Takes care of any comma/whitespace combinations (if any).
    for (int i = 0; i < values.length; i++) {
        csvLineElements[i] = values[i];
    }
        
    /* Is the csvLineElements[] element a String representation of a signed
       or unsigned integer data type value ("-?\\d+"). If so, convert the 
       String array element into an Integer value. If not, provide a default 
       value of 0.                                                       */
    int cumulPos = Integer.parseInt(csvLineElements[6].matches("-?\\d+") ? csvLineElements[6] : "0");
    int cumulDec = Integer.parseInt(csvLineElements[7].matches("-?\\d+") ? csvLineElements[7] : "0");
    int cumuRec = Integer.parseInt(csvLineElements[8].matches("-?\\d+") ? csvLineElements[8] : "0");
    int curPos = Integer.parseInt(csvLineElements[9].matches("-?\\d+") ? csvLineElements[9] : "0");
    int hosp = Integer.parseInt(csvLineElements[10].matches("-?\\d+") ? csvLineElements[10] : "0");
    int intenCar = Integer.parseInt(csvLineElements[11].matches("-?\\d+") ? csvLineElements[11] : "0");
    /* Is the csvLineElements[] element a String representation of a signed
       or unsigned integer or floating point value ("-?\\d+(\\.\\d+)?"). 
       If so, convert the String array element into an Double data type value. 
       If not, provide a default value of 0.0                             */
    double latitude = Double.parseDouble(csvLineElements[4]
                      .matches("-?\\d+(\\.\\d+)?") ? csvLineElements[4] : "0.0d");
    double longitude = Double.parseDouble(csvLineElements[5]
                      .matches("-?\\d+(\\.\\d+)?") ? csvLineElements[5] : "0.0d");
        
    /* Create an instance of Country to pass into the constructor of  
       CovidRecord below.           */
    Country country = new Country(csvLineElements[1], csvLineElements[2], 
                                  csvLineElements[3], csvLineElements[13], 
                                  latitude, longitude);
        
    // Create an add an instance of CovidRecord to the recordsList List.
    recordsList.add(new CovidRecord(csvLineElements[0], cumulPos, cumulDec, 
                                    cumuRec, curPos, hosp, intenCar, country));
        
    // Do what you want with the recordList List.... 
}

For obvious reasons, the code above was not tested. If you have any problems with it then let me know.

You will also notice the instead of the covidrecordArray[] CovidRecord Array I opted to use a List Interface named recordsList. This List can grow dynamically whereas the array is fixed meaning you need to determine the number of data lines within the file when initializing the array. This is not required with the List.

DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22
-1

you can create one generic method for null check and check if it's null then return empty string or any thing else based on your needs

  int hosp = Integer.parseInt(checkForNull(Values[10]));
   

    public static String checkForNull(String val) {

        return (val == null ? " " : val);
    }