Reputation: 3
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
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
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
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:
if (digit != ' ')
if (!Character.isWhiteSpace(digit)
if (Character.isDigit(digit))
Upvotes: 0
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