-2

I cannot figure how to obtain latest 4 char of string before zeroes

String str = "41f1f3d1f10000000000000000000000000000000000"

I want: d1f1

I've tried to revert string string than do straight loop

public static boolean checklast4digit(String risposta) {
    String crc = "";
    risposta = reverseIt(risposta);
    for (int i = 0; i < risposta.length(); i++) {
        if (risposta.charAt(i) != '0') crc = Character.toString(risposta.charAt(i + 3)) + Character.toString(risposta.charAt(i + 2)) + Character.toString(risposta.charAt(i + 1)) + Character.toString(risposta.charAt(i)); 
    }
    Log.i("Crc letto: ", crc);
    return true;
}

public static String reverseIt(String source) { //Inversione stringa
    int i, len = source.length();
    StringBuilder dest = new StringBuilder(len);

    for (i = (len - 1); i >= 0; i--) {
        dest.append(source.charAt(i));
    }

    return dest.toString();
}

Exception:

java.lang.StringIndexOutOfBoundsException
Ian2thedv
  • 2,691
  • 2
  • 26
  • 47

6 Answers6

0

There are many ways to improve your code, one of which would be to just remove the trailing zeroes first, then reverse the remaining string and take the first 4 chars of it.

However, to point out errors in your code...

Take a look at the values you're using to get characters. While your loop is limited to i<risposta.length(), i+3 that you're using in the line below is not - it can go up to risposta.length()+2. If oyu want to fix the code, then change the loop condition to i+3<risposta.length().

It's not elegant and can be done better, but that would solve the immediate bug in your code.

CptBartender
  • 1,235
  • 8
  • 22
0

Your IndexOutOfBoundsException is caused by:

risposta.charAt(i + 3)
risposta.charAt(i+2)
risposta.charAt(i+1)

If you take a look at your for loop:

for(int i=0 ; i < risposta.length(); i++){

}

You are iterating from index 0 to risposta.length() - 1. However because you are getting the char at i+3 when i is risposta.length() - 1 it tries to access the index risposta.length() + 2 which is out of bounds.

You ned to modify your loop so you only iterate up to risposta.length() - 3

explv
  • 2,709
  • 10
  • 17
0

As mentioned in the comments, you are looping too far. If you want to access charAt(i+3) you should only loop until i < risposta.length() - 3

Also, you need to break out of your loop, once you have found your result:

for(int i=0 ;i < risposta.length() - 3 ;i++){
    if(risposta.charAt(i) != '0') {
        crc= Character.toString(risposta.charAt(i + 3)) + Character.toString(risposta.charAt(i+2)) + Character.toString(risposta.charAt(i+1)) + Character.toString(risposta.charAt(i));
        break;
    } 
}

Note that this only gives you a result, if you have 4 non-zero characters before the zeros.

Keiwan
  • 8,031
  • 5
  • 36
  • 49
  • I have forgot break command, thank you !! It wil never loop to end, because char will be on first of the loop – Alessio Di Marco Jun 10 '16 at 14:19
  • If you gave it a string that didn't have at least 4 non-zero characters in the beginning, it would still fail without the `risposta.length() - 3` , even if you added the `break`. My version would just return an empty string instead of throwing an error. – Keiwan Jun 10 '16 at 14:32
0

Here you have a oneliner!

String a = new StringBuilder(new StringBuilder("41f1f3d1f10000000000000000000000000000000000".split("0")[0]).reverse().toString().substring(0, 4)).reverse().toString();

And the complete code looks like this:

package nl.testing.startingpoint;

public class Main {

public static void main(String args[]) {
        String a = new StringBuilder(new StringBuilder("41f1f3d1f10000000000000000000000000000000000".split("0")[0]).reverse().toString().substring(0, 4)).reverse().toString();
        System.out.println(a);
    }
}

result: d1f1

Igoranze
  • 1,506
  • 13
  • 35
0

First of all the StringBuilder has a reverse method, which you can use to revers a string. That would simplify the reversing quite a bit.

return new StringBuilder(source).reverse().toString();

and as the others pointed out your for loop probably causes the exception, as it iterates to long.

To remove all trailing zeros (as suggested by CptBartender) you can use regex.

risposta = risposta.replaceFirst("0+$");

Then you can reverse the string (as shown above) and get the first n characters using the substring method.

reversed.substring(0, Math.min(reversed.length(), 4));

Math.min() is used to ensure there is no error if there are less than 4 characters before the zeros.

Leon
  • 2,926
  • 1
  • 25
  • 34
0

Alternatively, you could strip the 0's with a replaceAll and then get the last 4 chars with a substring. That makes the code pretty simple:

public static void main(String[] args) {
    String str = "41f1f3d1f10000000000000000000000000000000000";
    str = str.replaceAll("0*$", "");
    System.out.println(str.substring(str.length()-4));
}
Arjan
  • 823
  • 1
  • 7
  • 18