0

I've decided to write my own subString method, however when I test it within my test driver I receive an error with one of my lines in my SubString method. This is the error:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 6
at java.lang.String.charAt(Unknown Source)
at unisa.util.StringImproved.subString(StringImproved.java:618)

This is my code for my subString:

    public String subString(int start, int end) {
    //empty string to append the new string's characters to
    String subString = "";
    //creating a new string to store content to allow function
    String s1 = new String(content);
    //read each character in the string and append based on the index
    for (int i=start; i<=end; i++){
        subString += s1.charAt(i);
    }
    //convert string back to a char array
    content = subString.toCharArray();
    return subString;

}

The error is picking up the line subString += s1.charAt(i); Anyone able to shed some light on what i'm doing wrong??

PS. this isn't for an assignment just a bit of boredom and wanting to re-create the java functions myself.

Thanks in advance!!

I have added my testing methods as per request!!

private int testSubString(String testID) {
    int errorCount=0;



    header(testID);

    {
        System.out.println("Test[getting substring from middle] ");
        StringImproved str = new StringImproved("0123456789");
        String result = str.subString(1,2);
        errorCount+=handleResult(result,"1")?0:1;
    }

    {
        System.out.println("Test[getting first characters] ");
        StringImproved str = new StringImproved("0123456789");
        String result = str.subString(0,2);
        errorCount+=handleResult(result,"01")?0:1;
    }

    {
        System.out.println("Test[getting last characters] ");
        StringImproved str = new StringImproved("0123456789");
        String result = str.subString(str.length()-3,str.length());
        errorCount+=handleResult(result,"789")?0:1;
    }


    {
        System.out.println("Test[out of range] ");
        StringImproved str = new StringImproved("0123456789");
        String result = str.subString(0,str.length()+1);
        errorCount+=handleResult(result,null)?0:1;
    }

    {
        System.out.println("Test[zero length source] ");
        StringImproved str = new StringImproved("");
        String result = str.subString(0,str.length()-1);
        errorCount+=handleResult(result,null)?0:1;
    }
    return errorCount;      
}
5
  • A bug is a discrepancy between actual behaviour and intended behaviour. Tell us what the intended behaviour is. There are perfectly valid reasons for throwing a StringIndexOutOfBoundsException on occassion. Also tell us with wich values your are testing the method. Commented Sep 22, 2013 at 10:11
  • The intended behaviour @Oswald is to basically the method be functional enough that no matter what string I put into the test driver I have created it should create a substring of that string. Commented Sep 22, 2013 at 10:18
  • What if it cannot compute the substring in a natural way, e.g. because start is larger than the length of the input string or end is larger than the length of the input string or start is larger than end, or start or end is negative? You have to at least think about what your method should do in these cases. You can leave it unspecified; but then, throwing a StringIndexOutOfBoundsException is acceptable behaviour for the mentioned input values. I do not know with wich values you tested your method, so I have no clue to why throwing a StringIndexOutOfBoundsException is wrong. Commented Sep 22, 2013 at 10:52
  • I have added my testing method in my original post if that helps. @Oswald Commented Sep 22, 2013 at 11:30
  • Follow the advice given by Maroun Maroun. When you have done that, you will also have to extend your method such that it examines the start and end arguments and the length of the input string so that you get the expected results in the cases out of range and zero length source (you return an empty string in those cases, but according to the tests you are doing, null is expected). Commented Sep 22, 2013 at 12:25

2 Answers 2

5

Arrays are zero-based.

If your string is of length N, the indexes are from 0 to N - 1 (Total length of N).

Your for loop should be:

                   ↓‎
for (int i=start; i<end; i++) {

Example:

"This is a test" is of size 14, T is on the 0 place, the last t is the 13 place.


As @sanbhat mentioned, you need to check some cases, for example, what will happen it the size of content is smaller than end?

Sign up to request clarification or add additional context in comments.

4 Comments

this will not work.. what if the length of content is smaller than end ?
@sanbhat This is to tell why exception occuring,Proper gaurd checkings needs to be placed by OP.We cannot cover all the things here :)
Atlest we can warn OP ? Above solution alone cannot fix the IndexoutofBound issue..isn't it? :)
@sanbhat Yes,Thumsup santosh :)
2

Change

for (int i = start; i <= end; i++){
   subString += s1.charAt(i);
}

to

for (int i = start; i < end; i++){
    subString += s1.charAt(i);
}

But this would be error prone, because it depends how do you invoke your own substring() method. The reason is that the parameters may exceed the length of the string (or be negative, for example).

A better approach is to make a couple of checks to ensure the parameters are valid.

if (start >= 0 && end >= start) {
   end = Math.min(myString.length(), end);
} else { 
   throw new IllegalArgumentException("Invalid arguments");
}

and the do the loops.

You should also note, that the String#chatAt(int i) method returns the character of the zero-based char[] array that represents the String object.

3 Comments

I made the change to the for loop but it's still returning an error: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 10 at java.lang.String.charAt(Unknown Source) unisa.util.testing.TestDriverPublic.testStringImproved(TestDriverPublic.java:108) At the specific for loop.
How do you invoke the method ?
I'm not necessarily invoking them but putting the methods through tests with different strings if that makes sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.