LifesAHaskell
LifesAHaskell

Reputation: 3

modify empty characters in a character array

I'm attempting to take in a string from the console of a certain length and set the empty characters in the string to an asterisk.

System.out.println("Enter a string of digits.");

        someString = input.next();

        if(someString.matches("\\d{0,9}")) {

            charArr = someString.toCharArray();

            for ( char digit: charArr) {
                if(!Character.isDefined(charArr[digit])){
                    charArr[digit] = '*';
                }
            }

            System.out.printf("Your string is: %s%n", new String(charArr));

This code is throwing an array index out of bounds exception and I'm not sure why.

Upvotes: 0

Views: 90

Answers (4)

rlbaker
rlbaker

Reputation: 113

Think you could do it in one line with:

newString  = someString.replaceAll("\\s", "*");

"\s" is the regex pattern for a whitespace character.

Upvotes: 0

Stephen C
Stephen C

Reputation: 718688

This loop statement:

for (char digit: charArr) {

iterates the values in the array. The values have type char and can be anything from 0 to 65535. However, this statement

    if (!Character.isDefined(charArr[digit])) {

uses digit as an index for the array. For that to "work" (i.e. not throw an exception), the value needs to be in the range 0 to charArr.length - 1. Clearly, for the input string you are using, some of those values are not acceptable as indexes (e.g. value >= charArr.length) and an exception ensues.

But you don't want to fix that by testing value is in the range required. The values of value are not (from a semantic perspective) array indexes anyway. (If you use them as if they are indexes, you will end up missing some positions in the array.)

If you want to index the values in the array, do this:

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

and then use i as the index.


Even when you have fixed that, there is still a problem with your code ... for some usecases.

If your input is encoded using UTF-8 (for example) it could include Unicode codepoints (characters) that are greater than 65535, and are encoded in the Java string as two consective char values. (A so-called surrogate pair.) If your string contains surrogate pairs, then isDefined(char) is not a valid test. Instead you should be using isDefined(int) and (more importantly) iterating the Unicode codepoints in the string, not the char values.

Upvotes: 0

Lincoln Anders
Lincoln Anders

Reputation: 91

I think you're mixing your for blocks. In your example, you're going over every character in your someString.toCharArray() so you can't do !Character.isDefined(charArr[digit]) because digit is a char, not an int. You can't take the index of an array with a char.

If you're checking purely if a character is a space, you can simply do one of the following:

  1. if (digit != ' ')
  2. if (!Character.isWhiteSpace(digit)
  3. if (Character.isDigit(digit))

Upvotes: 0

Devendra Lattu
Devendra Lattu

Reputation: 2802

for ( char digit: charArr) will iterate over each character from charArr.
Thus, digit contains a character value from charArr.

When you access the element from charArr by writing charArr[digit], you are converting digit from datatype char to int value.

For example, you have charArr = new char[]{'a','b','c'}.
charArr['a'] is equivalent to charArr[97] but charArr has size of length 3 only.

Thus, charArr cannot access the element outsize of its size and throws ArrayIndexOutOfBoundsException.


Solution: loop through the array index wise rather than element wise.

for(int i = 0; i < charArr.length; i++) {
   // access using charArr[i] instead of charArr[digit]
   ...
}

Upvotes: 1

Related Questions