Win a copy of Transfer Learning for Natural Language Processing (MEAP) this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Paul Clapham
  • Devaka Cooray
  • Bear Bibeault
Sheriffs:
  • Junilu Lacar
  • Knute Snortum
  • Liutauras Vilda
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Piet Souris
Bartenders:
  • salvin francis
  • Carey Brown
  • Frits Walraven

Help: ArrayIndexOutOfBoundsException when I read a text file, but the details can be printed

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello! I'm a new java programmer.

I'm using .substring to read a specific part of a string from a text file. Here's a sample of the string to be read:

2093505,"AMBROS, RALPH HENRY B",BS Entrep 1,M,23,93.94

We're supposed to ignore the quotes, which is why I'm using substring. When I run the program though, I get this error:



This is the code where the error is:



I caught the error using a try/catch before, I took it off to see where I went wrong.

I can print the details just fine. They show up in order and everything, but it still gives me the OutofBounds error for all of the details (id, name, year, etc). Where am I going wrong?

Sample output:




Thank you for any help you can give.
 
Saloon Keeper
Posts: 6380
158
Android Mac OS X Firefox Browser VI Editor Tomcat Server Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch.

Which one is line 54 (where the error occurs)?

Two things:

1) You should check that studentData.length is exactly what you expect it to be before proceeding.

2) This looks like CSV data . You may be better off using a CSV library rather than trying to parse the data this way. This avoids the awkward code that handles the name, and all the other CSV oddities that this code punts on.
 
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Don't close your reader explicitly. Use try with resources. If any exception occurs between lines 3 and 25, you are not guaranteed to close the file correctly.
Don't read the line and use it in the same place. The two belong in different methods.
I think the List should be a field, not a local variable. Much more object‑oriented.
Don't use while (true) ... You have to use the following strange looking syntax with the = inside () as in line 6.The () are needed to ensure that the assignment to line is executed before the test for null; otherwise the code won't compile. I am guessing about which charset and encoding you are using.

I don't think the exception has anything to do with your reading quotes. It is the wrong sort of exception. I think you are missing the problem because your debugging code is obscuring something. You are right to use print statements for debugging, but I suspect you are missing a short line. Change line 9 to this:-...which will give you the output with “quotes” round it. I suspect you have a non‑null line which doesn't contain a comma. Most text files end with a line end sequence, but maybe your file is ending with a short line. If youi print out spaces, you won't notice anything, but if you add quotes and find you have a line looking like this

“ ”

...then you can regard your input file as corrupted by a line containing only a space. In that case, split() will divide that line into a one‑element String[] (remember your stack trace says length 1), and you will suffer an exception.

[additional]Please add an extra ) to the end of line 3 in both code blocks.
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I would use a Scanner to read the file, not a buffered reader:-The reason for using two Scanners is to use different delimiters. When the Scanner scan reaches a line containing only spaces, the hasNext() call will return false and the loop will terminate before you have a chance to suffer any exceptions. It would be better if lines 9‑16 were moved to a method of their own.

I think there is an error in my first post. I think there should be an additional ) at the end of line 3.

Go through the Java™ Tutorials to find out about Paths.get() rather than new File(...)
 
Tim Moores
Saloon Keeper
Posts: 6380
158
Android Mac OS X Firefox Browser VI Editor Tomcat Server Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the file actually contains CSV, I strongly recommend to use an existing library. Everything else will be very brittle.
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe they have been told to use such low‑level reading to practise with Readers.
 
Yuri Videz
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello again!


I think I would use a Scanner to read the file, not a buffered reader:-



@Campbell Ritchie, Thank you! Your solution fixed the ArrayOutofBounds error. However, I'm getting a new one. When it comes to reading the year, I get the following:



I tried adjusting the Delimiters, but I don't quite understand how they work yet.


When the Scanner scan reaches a line containing only spaces, the hasNext() call will return false and the loop will terminate before you have a chance to suffer any exceptions.



How would I adjust the Delimiters to make this true?

2093505,"AMBROS, RALPH HENRY B",BS Entrep 1,M,23,93.94

BS Entrep should be read separately from 1--it's another challenge from our teacher.  

Thank you, again, for all your help. I tried asking the people over at StackOverflow but they were kind of condescending. I'll definitely use coderanch from now on.
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please wait: shall be busy for a few hours. Sorry.
 
Yuri Videz
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you! It's okay, I understand, thank you for giving me your time. I am happy to wait
 
Sheriff
Posts: 7052
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem with Campbell's solution is that it's not going to get that "data, with comma" should all be one token (chuck of data).  In your case, the second token is only AMBROS, not AMBROS, RALPH HENRY B.

Unless this is an assignment on how to write a CSV parser, please look into the existing CSV Parser libraries, like:

http://commons.apache.org/proper/commons-csv/

It's going to be a bit complex at first, especially if you haven't used a Java library before, but it will be worth it in the end.
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Yuri Videz wrote:. . . it's another challenge . . . .

💀@🕱☁☇‍‍¿!!⁇
If anybody gives you such a “challenge” in real life, tell them that is a corrupted file and hit them. Hard. Remember that you can kill lots more people all at once with dangerous computing than with dangerous driving. Ask any 737Max8 pilot.
Tim M is right. Writing your own CSV parser is difficult and error‑prone enough without additional challenges like that.

Do all the lines have the comma missing there? What is happening is that you are reading “BS Entrep 1” as one token, which Knute has already pointed out. That is because it doesn't contain any commas, and you will then be trying to turn the token after the next comma, viz. “M” into a number, which won't work.
How many spaces are there going to be in that sort of text? Will it always be two? There is probably a way you can split that token using the String#split method and " " as your regex and telling it to miss out the first space. But, as others have told you, this is error‑prone and brittle code.

I have realised that it is possible to use one Scanner without changing delimiter because you can call nextLine() and ignore the returned value to move you onto the next line. You could also reset the Scanner to its default delimiter during the scanning of “BS Entrep 1” and use the delimiter with commas in after that. But it should be very obvious that we are in the realms of complicated code here. I presume you have read the documentation for Scanner? Have a look at the Java™ Tutorials about regular expressions.

Knute Snortum wrote:The problem with Campbell's solution is that it's not going to get that "data, with comma" should all be one token (chuck of data).

I missed that you wanted name all as one token. Sorry. My regex will separate the name into two parts. You could try using "\\\"\\s*,\\s*" as a delimiter just to finish reading the name, but that code is getting more and more complicated by the minute. I have an unjustified assumption that anything that complicated is wrong regardless!
 
Yuri Videz
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Yuri Videz wrote:. . . it's another challenge . . . .

💀@🕱☁☇‍‍¿!!⁇
If anybody gives you such a “challenge” in real life, tell them that is a corrupted file and hit them. Hard. Remember that you can kill lots more people all at once with dangerous computing than with dangerous driving. Ask any 737Max8 pilot.
Tim M is right. Writing your own CSV parser is difficult and error‑prone enough without additional challenges like that.

Do all the lines have the comma missing there? What is happening is that you are reading “BS Entrep 1” as one token, which Knute has already pointed out. That is because it doesn't contain any commas, and you will then be trying to turn the token after the next comma, viz. “M” into a number, which won't work.
How many spaces are there going to be in that sort of text? Will it always be two? There is probably a way you can split that token using the String#split method and " " as your regex and telling it to miss out the first space. But, as others have told you, this is error‑prone and brittle code.

I have realised that it is possible to use one Scanner without changing delimiter because you can call nextLine() and ignore the returned value to move you onto the next line. You could also reset the Scanner to its default delimiter during the scanning of “BS Entrep 1” and use the delimiter with commas in after that. But it should be very obvious that we are in the realms of complicated code here. I presume you have read the documentation for Scanner? Have a look at the Java™ Tutorials about regular expressions.

Knute Snortum wrote:The problem with Campbell's solution is that it's not going to get that "data, with comma" should all be one token (chuck of data).

I missed that you wanted name all as one token. Sorry. My regex will separate the name into two parts. You could try using "\\\"\\s*,\\s*" as a delimiter just to finish reading the name, but that code is getting more and more complicated by the minute. I have an unjustified assumption that anything that complicated is wrong regardless!




Thanks for your help!

Yes, our teacher isn't the best. He glosses over everything and basically leaves us to figure stuff out on our own, gets mad when we ask him questions, is really old-school etc--we're kind of teaching ourselves, here, while trying to meet his standards at the same time.

The name doesn't have to be all one token. The task is to sort Student objects by program, age, then passing or failing, which I can do.
Do you think Having the program String as "BS Entrep 1" would matter in that regard?

I came up with this to separate the year. Doing this put everything in place including age, gender, average, etc, but I get another strange OutOfBounds error although I counted the String's length, and it shouldn't be giving me an out of Bounds:



This is the error:
java.lang.StringIndexOutOfBoundsException: String index out of range: 10
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
at java.base/java.lang.String.charAt(String.java:709)
at edu.slu.prog2.finals2.VidezStudentsRecords.readDataFileIntoList(VidezStudentsRecords.java:61)
at edu.slu.prog2.finals2.VidezStudentsRecords.run(VidezStudentsRecords.java:29)
at edu.slu.prog2.finals2.VidezStudentsRecords.main(VidezStudentsRecords.java:21)



I checked the length of the program string beforehand, and it was 11, which means I should be just fine with the .charAt(10) to get the year.

Thank you for your time. I can't stress how much I appreciate it. It's kind of new for me to find places where I can genuinely get help
 
Yuri Videz
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Update: I realized I was getting an out of bounds error because the length of the Program String varied. I was able to get it to output everything right by using the code below with no errors:



All I have to fix now is the sorting of the List of students I'm new to that too, but I'll study how to do it as best as I can. Thank you so much for your time and help! You all helped me go in the right direction for this one.
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Getting better I am afraid there are two serious logic errors are in that code. It isn't necessary to use valueOf() to turn a String into a String.
 
Yuri Videz
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Getting better I am afraid there are two serious logic errors are in that code. It isn't necessary to use valueOf() to turn a String into a String.



Thank you! I adjusted that
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You haven't corrected the other two errors.
 
Yuri Videz
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:You haven't corrected the other two errors.



Sorry for the late reply. What were the errors? I removed the String.valueOf around them

 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What happens when the String input is, “Computing 3”?
What happens when the String input is, “BSc Computing 3”?
What happens when the String input is, “BSc Java Computing 3”?
What happens when the String input is, “BSc Basic Java Computing 3”?
What happens when the String input is, “BSc Basic Object Oriented Java Computing 3”?

Ignore the fact that you are using ordinary spaces for splitting the String and I am posting hard spaces. Assume the delimiter will split on hard spaces too. Try splitting with "\\s+" which should split on hard spaces too.
 
Knute Snortum
Sheriff
Posts: 7052
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Even though the OP perhaps doesn't need a general CSV parser, here's one I wrote that works pretty well:
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

On Saturday, I wrote:What happens when the String input is, “Computing 3”?  . . .

Since OP hasn't returned, maybe I should point out the two 2½ errors I noticed.
  • 1: The two ifs will neitheer of them be executed if the array has leength 3.
  • 2: It is wrong to assume that the indices for the number will be 1. In some of the examples I posted the index for the number is 4 or 5.
  • 2½: It is wrong to assume that the index for the number will be 3. In some of the examples I posted the index for the number is 4 or 5.
  • Actually, theere is a straightforward way to find the number with an array index without any ifs.
     
    Yuri Videz
    Greenhorn
    Posts: 8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Sorry I didn't reply yesterday. My town was hit with heavy rains that cut off my power.

    Thank you for correcting me, I'll find a way to implement what you said
     
    Campbell Ritchie
    Marshal
    Posts: 68909
    275
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I thought it was strange that you didn't reply; I hope all is back to normal now.
     
    No more fooling around. Read this tiny ad:
    Two software engineers solve most of the world's problems in one K&R sized book
    https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
      Bookmark Topic Watch Topic
    • New Topic