Java Exception: java.lang.StringIndexOutOfBoundsException - java

I have some problems with the code every time I try to compile the exception java.lang.StringIndexOutOfBoundsException appears. Here is the code with the problem I really don't know what I have done wrong. In the code I try to split a string using some conditions, the string represent a polynomial.
int[] coef1= new int[20];
for(i=0;i<polinom.length()+1;i++){
if(polinom.charAt(i)=='+' )
c=polinom.charAt(i+1);
else{
if(polinom.charAt(i)=='^'){
v=Integer.parseInt(Character.toString(polinom.charAt(i+1)));
coef1[v]=Integer.parseInt(Character.toString(c));
System.out.print(coef1[v]);
}
}
}
for(i=0;i<polinom.length()+1;i++){
if(polinom.charAt(i)=='-' )
c=polinom.charAt(i+1);
else{
if(polinom.charAt(i)=='^'){
v=Integer.parseInt(Character.toString(polinom.charAt(i+1)));
coef1[v]=-Integer.parseInt(Character.toString(c));
System.out.print(coef1[v]);
}
}
}
The exception is here if(polinom.charAt(i)=='+' )

Just replace all your
for(i=0;i<polinom.length()+1;i++){
with
for(i=0;i<polinom.length()-1;i++){
As indices are 0-based and you use polinom.charAt(i+1), i+1 should never be equal (nor greater) than polinom.length.
Or if you want ot be able to test until the last character of you string (for other processing), you can ensure that polinom.charAt(i+1) gets never triggered if i == polinom.length() - 1, just add a test before processing your stuff:
for(i=0;i<polinom.length();i++){ // not using -1, looping to the end of the string
if(polinom.charAt(i)=='+' && i < polinom.length() - 1) // checking that no exception will be thrown
c=polinom.charAt(i+1);
else{
if(polinom.charAt(i)=='^' && i < polinom.length() - 1){ // same
v=Integer.parseInt(Character.toString(polinom.charAt(i+1)));
coef1[v]=-Integer.parseInt(Character.toString(c));
System.out.print(coef1[v]);
}
}
}

In the second line here you are using
for(i=0;i<polinom.length()+1;i++){
That +1 should be -1.

I suppose the variable polinom is a String.
Your're looping beyond the end of the string:
for(i=0;i<polinom.length()+1;i++)
It should be
for(i=0;i<polinom.length()-1;i++)

Related

"Find substring in char[]" getting unexpected results

Disclaimer: This is a bit of a homework question. I'm attempting to write a contains(java.lang.String subString) method , that returns an int value representing the index of the comparison string within the primary string, for a custom-made String class.
Some of the rules:
No collection classes
Only charAt() and toCharArray() are allowed from the java String class (but methods from other classes are allowed)
Assume length() returns the length of the primary string (which is exactly what it does)
My Code:
public int contains(java.lang.String subString) {
this.subString = subString;
char[] arrSubStr = this.subString.toCharArray();
//Create initial fail
int index = -1;
//Make sure comparison subString is the same length or shorter than the primary string
if(arrSubStr.length > length()) {
return index;
}
//Steps to perform if initial conditions are met
else {
//Compare first character of subString to each character in primary string
for(int i = 0; i < length(); i++) {
//When a match is found...
if(arrSubStr[0] == this.content[i]) {
//...make sure that the subString is not longer than the remaining length of the primary string
if(arrSubStr.length > length() - i) {
return index;
}
//Proceed matching remainder of subString
else {
//Record the index of the beginning of the subString contained in primary string
index = i;
//Starting with second character of subString...
for(int j = 1; j < arrSubStr.length;) {
//...compare with subsequent chars of primary string,
//and if a failure of match is found, reset index to failure (-1)
if(arrSubStr[j] != this.content[j+i]) {
index = -1;
return index;
}
//If we get here, it means whole subString match found
//Return the index (=i) we set earlier
else {
return index;
}
}
}
}
}
}
return index;
}
Results from testing:
Primary string: asdfg
Comparison string: donkey
Result: -1 [PASS]
Primary string: asdfg
Comparison string: asdfg
Result: 0 [PASS]
Primary string: asdfg
Comparison string: g
Result: 4 [PASS]
Primary string: asasasf
Comparison string: asd
Result: 0 [FAIL] (should be -1)
Primary string: asasasf
Comparison string: asf
Result: 0 [FAIL] (should be 4)
The comments reflect how the code is intended to work. However its clear that when it reaches the second for loop, the logic is breaking down somehow to give the results above. But I can't see the problem. Could I get a second set of eyes on this?
//If we get here, it means whole subString match found
//Return the index (=i) we set earlier
else {
return index;
}
This assumption is not correct unfortunately. If you get there, it means that the second character of both substrings are identical since the if-else statement will only get executed once and both ends contains a return.
The way to solve this is probably easy now that I've diagnosed the problem but I want to go a bit further with this. The way we try to write code on a daily basis is a way in which the code we use can be maintainable, reusable and testable.
This means basically that the function we have here could be easily sliced up in different little functions invoked one after the other for which we could write unit tests and receive a quick feedback on whether a set of logical statements fit or not.
With suggestions from Jai and azurefrog in the comments, I was able to solve the issues by re-writing the logic to the following (somewhat abridged):
if(arrSubStr.length > length()) {
return index;
}
//Steps to perform if initial conditions are met
else {
//Compare first character of subString to each character in primary string
for(int i = 0; i < length(); i++) {
//When a match is found...
if(arrSubStr[0] == this.content[i]) {
//...make sure that the subString is not longer than the remaining length of the primary string
if(arrSubStr.length <= length() - i) {
//Record the index of the beginning of the subString contained in primary string
index = i;
//Starting with second character of subString...
for(int j = 1; j < arrSubStr.length; j++) {
//...compare with subsequent chars of primary string,
//and if a failure of match is found, reset index to failure (-1)
if(arrSubStr[j] != this.content[j+i]) {
index = -1;
break;
}
}
}
}
}
}
return index;
Essentially, I removed all of the return statements from within the loops. Simply setting the index value appropriately and making use of the final (outside) return statement was, in hindsight, the correct way to approach the problem. I then also added a break; to the inner for loop to make sure that a failure to match would continue the loop ticking through. I'm sure there's still unnecessary code in there, but while its still passing the requisite tests, I'm encouraged to leave it the hell alone. :)
I'm still a novice at Java, so I hope this explanation made sense.

Strange(?) out - of - bound with Stringuilder on array

There last 2 days I am 100% brain dead and cant find where the error is... Can anyone give me a tip >>
for(String inputString : word)
{
StringBuilder sb = new StringBuilder(inputString);
if(inputString.charAt(inputString.length()-1) == ']')
{
sb.deleteCharAt(inputString.length());
}
else if(inputString.charAt(0) == '[')
{
sb.deleteCharAt(0);
}
breaker.add(sb.toString());
}
It was suppose to be a simple function to remove the [ ] characters from a string but everytime I run it I get
Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
But only on the third or fourth pass never the first or second.
Confused.
sb.deleteCharAt(inputString.length());
should be
sb.deleteCharAt(inputString.length() - 1);
Because you want to remove the last character (you did it correctly in the test!)
You're deleting the last char at the StringBuilder's length, rather than length - 1.
StringBuilder, not unlike all String and array representations in Java, is 0-indexed.
Use the following idiom instead:
sb.deleteCharAt(sb.length() - 1);
The reason why the StringIndexOutOfBoundsException is only thrown arbitrarily in your execution is likely because of the condition checking for the ] character, which may not always hold true (hence the offending code would not execute).

How to check the end of args array?

I am writing a parser program in Scala that should read input using "args" and pars it. It doesn't matter I use:
while(!args.isEmpty){
if (Files.exists(Paths.get(args(j)))){
Statement=Statement.concat(inputXml)
Statement=Statement.concat(" ")
println(j)
}
else{
Statement=Statement.concat(args(j))
Statement=Statement.concat(" ")
println(j)
}
j=j+1
}
or
while(args.length !=0) {
if (Files.exists(Paths.get(args(j)))){
Statement=Statement.concat(inputXml)
Statement=Statement.concat(" ")
println(j)
}
else{
Statement=Statement.concat(args(j))
Statement=Statement.concat(" ")
println(j)
}
j=j+1
}
The program gives me run time exception of array index out of bound! sending 2 values as input:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
what should I do? I am confused!
Your exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
Is because you are not breaking the while loop; the args parameter never change it's size, so your while will go forever util j exceed the size of args.
Maybe you could try:
int i = 0
while (i < args.length){
// some code here
i++;
}
or
for(int i = 0; i < args.length; i++){
// some code here
}
If you want to iterate through all the array
From what you describe, you need to iterate through your array while your index is lower than the maximum array size. If you merely compare args.length value, the loop condition will continue to evaluate to a truth value infinitely, since args.length will always be different than 0 (if not changed).
You need something along the lines of:
for(i <- 0 until array.length){
...
You can find extra information on accessing and iterating over arrays here and here
Consider iterating over args without using indexed references (the source of out-of-bounds error),
for ( arg <- args ) yield {
if (Files.exists(Paths.get(arg))) xmlFile
else ""
}.mkString(" ")
This for comprehension yields a collection of String which is converted to a space-separated string with mkString.

Out of Bounds Exception on a 2D Ragged Array in Java

Problem solved, I ended up need a seperate counter for the array position. Thanks for the help!
I'm writing a small app that takes a string, processes each string into 7-bits of binary code and then fills in a musical scale based on the string. For instance, if I had the binary 1000100, in the key of C Major that would give me the notes C and G(C 0 0 0 G 0 0).
I'm having an issue with a specific piece of code that takes an input of String[] (in which each element is a single character worth of binary, 7-bits) and processes each individual character in the strings themselves and stores the index number of where 1's occur in the string. For example, the string 1000100 would output 1 and 5.
Here's the method that does that:
public static String[][] convertToScale(String[] e){
String[][] notes = new String[e.length][]; //create array to hold arrays of Strings that represent notes
for(int i = 0; i < e.length; i++){
notes[i] = new String[findOccurancesOf(e[i])]; //create arrays to hold array of strings
for(int x = 0; x < e[i].length(); x++){
if((e[i].charAt(x)) != 48){ //checks to see if the char being evaluated is 0(Ascii code 48)
notes[i][x] = Integer.toString(x + 1); // if the value isn't 0, it fills in the array for that position.the value at x+1 represents the position of the scale the note is at
}
}
}
return notes;
}
Here is the code that is uses to get the occurrences of 1 in e[1]:
public static int findOccurancesOf(String s){
int counter = 0;
for(int i = 0; i < s.length(); i++ ) {
if( s.charAt(i) == 1 ) {
counter++;
}
}
return counter;
}
The issue I'm having is with the convertToScale method. When using "Hello world" as my input(the input gets converted into 7-bit binary before it gets processed by either of these methods) it passes through the 2nd for-each loop just fine the first time around, but after it tries to fill another spot in the array, it throws
java.lang.ArrayIndexOutOfBoundsException: 3
EDIT:It occurs in the line notes[i][x] = Integer.toString(x + 1); of the convertToScale method. I've run the debugger multiple times through after trying the proposes changes below and I still get the same error at the same line. The findOccurancesOf method returns the right value(When evaluating H(1001000) it returns 2.) So the thing that confuses me is that the out of bounds exception comes up right when it fills the 2nd spot in the array.
Also, feel free to tell me if anything else is crazy or my syntax is bad. Thanks!
In findOccurancesOf():
if( s.charAt(i) == 1 ) { should be if( s.charAt(i) == '1' ) { to check for the character '1'.
Otherwise it's looking for the character with ASCII value 1.
There is an out of bounds exception because if findOccuranceOf() returns the wrong value, then notes[i] is not constructed with the correct length in the following line of convertToScale():
notes[i] = new String[findOccurancesOf(e[i])];
In addition, you probably want to use something like:
notes[i][c++] = Integer.toString(x + 1);
with some counter c initialized to 0, if I understand your intentions correctly.
The reason for AIOOBE lies in this line:
notes[i] = new String[findOccurancesOf(e[i])]; //create arrays to hold array of strings
Where you call findOccurancesOf method to find occurance of 1 in your String say Hello which you dont find and return 0 and then you call notes[i][x] = Integer.toString(x + 1); with x as 0. Now since you never allocated space, you get array index out of bound exception.
I would suggest the folowing:
Validate your string before assigning the index say to be greater than 0 or something.
Initialize you notes[i] as notes[i] = new String[e[i].length];
Checking character with single quotes like a == '1' rather than a == 1
The exception is caused by what almas mentioned, note however, that your logical error is most likely inside findOccurencesOf method, if the idea was to find all the '1' chars inside a string you must change to what I outlined below, note the apostrohes. Otherwise a char is getting converted to a byte ascii code, and unless matched with a code of ascii code one, the method will return 0, causing your exception
if( s.charAt(i) == '1' ) {

Java - "String index out of range" exception

I wrote this little function just for practice, but an exception ("String index out of range: 29") is thrown and I don't know why...
(I know this isn't the best way to write this function and can I use regular expressions.)
This is the code:
public String retString(String x)
{
int j=0;
int i=0;
StringBuffer y = new StringBuffer(x);
try
{
while ( y.charAt(i) != '\0' )
{
if (y.charAt(i) != ' ')
{
y.setCharAt(j, y.charAt(i));
i++;
j++;
}
else
{
y.setCharAt(j, y.charAt(i));
i++;
j++;
while (y.charAt(i) == ' ')
i++;
}
}
y.setCharAt(j,'\0');
}
finally
{
System.out.println("lalalalololo " );
}
return y.toString();
}
Are you translating this code from another language? You are looping through the string until you reach a null character ("\0"), but Java doesn't conventionally use these in strings. In C, this would work, but in your case you should try
i < y.length()
instead of
y.charAt(i) != '\0'
Additionally, the
y.setCharAt(j,'\0')
at the end of your code will not resize the string, if that is what you are expecting. You should instead try
y.setLength(j)
This exception is an IndexOutOfBoundsException but more particularly, a StringIndexOutOfBoundsException (which is derived from IndexOutOfBoundsException). The reason for receiving an error such as this is because you are exceeding the bounds of an indexable collection. This is something C/C++ does not do (you check bounds of collections manually) whereas Java has these built into their collections to avoid issues such as this. In this case, you're using the String object like an array (probably what it is in implementation) and going over the boundary of the String.
Java does not expose the null terminator in the public interface of String. In other words, you cannot determine the end of the String by searching for the null terminator. Rather, the ideal way to do this is by ensuring you do not exceed the length of the string.
Java strings are not null-terminated. Use String.length() to determine where to stop.
Looks like you are a C/C++ programmer coming to java ;)
Once you have gone out of range with .charAt (), it doesn't reach null, it reaches a StringIndexOutOfBoundsException. So in this case, you will need a for loop that goes from 0 to y.length()-1.
a much better implementation (with regex) is simply return y.replaceAll("\\s+"," "); (this even replaces other whitespace)
and StringBuffer.length() is constant time (no slow null termination semantics in java)
and similarly x.charAt(x.length()); will also throw a StringIndexOutOfBoundsException (and not return \0 like you'd expect in C)
for the fixed code:
while ( y.length()>i)//use length from the buffer
{
if (y.charAt(i) != ' ')
{
y.setCharAt(j, y.charAt(i));
i++;
j++;
}
else
{
y.setCharAt(j, y.charAt(i));
i++;
j++;
while (y.charAt(i) == ' ')
i++;
}
}
y.setLength(j);//using setLength to actually set the length
btw a StringBuilder is a faster implementation (no unnecessary synchronization)

Categories