0

I need to read data from file in the format: int, Name nameClass, String, String, String, Scores [int,int,int,int,int], for example

150, John, Smith, USA, Active, Pro, 3,4,3,4,4

After running the code I get the following error

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
    at java.lang.String.charAt(String.java:658)
    at f1_final.CompetitorList.processLine(CompetitorList.java:184)
    at f1_final.CompetitorList.readFile(CompetitorList.java:149)
    at f1_final.FileWriterComp.main(FileWriterComp.java:14)

I figured out that this is due to me trying to copy int to a String. How can i go around and get this fixed?

private void processLine(String line)   {
    String compNo = "";

    try {
        String [] parts = line.split(",");
        nameClass compName = new nameClass(parts[1], parts[2]);
        compNo = parts[0];
        compNo = compNo.trim();


        String compCountry = parts[3];
        String compLevel = parts [4];
        String compActive = parts[5];

        int compNumber = Integer.parseInt(compNo);
        int compScoreLength = parts.length-6;
        int cScore[] = new int[compScoreLength];

        System.arraycopy(parts, 6, cScore, 0, compScoreLength);         // this line is causing problems which I wasnt able to fix. The program is unable to read arrays from file.

    //  int[]cScore = new int [compScoreLength];
    //  for(int i=0 ; i< compScoreLength ; i++)
    //          cScore[i] = parts[6].charAt(i)-'0';


        Competitor c = new Competitor(compNumber, compName, compCountry, compLevel, compActive, cScore);
        this.addOneCompetitor(c);
    }
  • Please see https://stackoverflow.com/questions/5554734/what-causes-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it – Progman Oct 20 '19 at 11:31
  • And you might want to look at https://stackoverflow.com/questions/785586/how-can-split-a-string-which-contains-only-delimiter – Progman Oct 20 '19 at 11:32
  • `compScoreLength` is related to the number of parts, so `i` is related to the number of parts, but then `parts[6].charAt(i)` means that you believe that the *length* of the 7th parts is related to the *number* of parts? That doesn't make any sense. – Andreas Oct 20 '19 at 11:44

2 Answers2

0

The stach trace clearly indicated an exception in java.lang.String.charAt(String.java:658), which is called in the part you uncommented. It seems you did not rebuild after you uncommented it. Note that System.arraycopy() only works if source and target array have the same type.

You have to manually convert each element:

  int[]cScore = new int [compScoreLength];
  for(int i=0 ; i< compScoreLength ; i++)
          cScore[i] = Integer.parseInt(parts[6 + i]);

You have in this example parts[6] = "3", parts[7] = "4", parts[8] = "3",..., all of them are a String.

Dorian Gray
  • 2,913
  • 1
  • 9
  • 25
0

The System.arraycopy() method can copy arrays of the same type but not a string array to an integer array. You end up with an ArrayStoreException. You could do it this way...here is your method. I've added some data validation and defaulting:

private void processLine(String line) {
    /* RegEx to eliminate the need for trim after parsing. 
       Handles all comma/space situations.   */
    String splitExp = "\\s{0,},\\s{0,}";

    // Split the file line into a string array.
    String[] parts = line.split(splitExp);

    // Make sure the CompNo is a string integer numerical value
    if (!parts[0].matches("\\d+")) {
        System.err.println("Invalid 'Comp Number' Detected!");
        return;  // exit this method.
    }
    int compNumber = Integer.parseInt(parts[0]); // parts[0] is obviously valid

    if (parts[1].equals("") || parts[2].equals("")) {
        System.err.println("Invalid 'Name' Components Detected!");
        return;  // exit this method.
    }

    /* 'Ternary Operator' is used to ensure a default is 
       used if name elements are invalid.       */
    nameClass compName = new nameClass(
            (parts[1].equals("") ? "UNKNOWN" : parts[1]),
            (parts[2].equals("") ? "UNKNOWN" : parts[2])
            );

    /* Again, 'Ternary Operator' is used to ensure a default 
       is used if elements are invalid.       */
    String compCountry = parts[3].equals("") ? "UNKNOWN" : parts[3];
    String compLevel = parts[4].equals("") ? "UNKNOWN" : parts[4];
    String compActive = parts[5].equals("") ? "UNKNOWN" : parts[5];

    // Get Scores - Create and fill a cScore integer array.
    int[] cScore = new int[parts.length - 6];
    for (int i = 6; i < parts.length; i++) {
        // Is this a valid score number
        if (!parts[i].matches("\\d+")) {
            System.err.println("The #" + (i + 1) + " score value ("
                    + parts[i] + ") is not a valid score number! "
                    + "0 will be used in its place!");
            /* Because i started a index 6 we subract 6 
               from i to get the true required index value
               for cScore       */
            cScore[i-6] = 0; 
        }
        else {
            /* Only valid string representations of integer 
               values will pass through here.            */
            cScore[i-6] = Integer.parseInt(parts[i]);
        }
    }

    Competitor c = new Competitor(compNumber, compName, compCountry, compLevel, compActive, cScore);
    this.addOneCompetitor(c);
}
DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22