VBozh
VBozh

Reputation: 13

Capitalization of the words in string

How can I avoid of StringIndexOutOfBoundsException in case when string starts with space (" ") or when there're several spaces in the string? Actually I need to capitalize first letters of the words in the string.

My code looks like:

public static void main(String[] args) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = reader.readLine();
    String[] array = s.split(" ");

    for (String word : array) {
        word = word.substring(0, 1).toUpperCase() + word.substring(1); //seems that here's no way to avoid extra spaces
        System.out.print(word + " ");
    }
}

Tests:

Input: "test test test"

Output: "Test Test Test"


Input: " test test test"

Output:

StringIndexOutOfBoundsException

Expected: " Test Test test"

I'm a Java newbie and any help is very appreciated. Thanks!

Upvotes: 0

Views: 118

Answers (6)

Anatolii Shuba
Anatolii Shuba

Reputation: 6185

Capitalize whole words in String using native Java streams

It is really elegant solution and doesnt require 3rd party libraries

    String s = "HELLO, capitalized worlD! i am here!     ";
    CharSequence wordDelimeter = " ";

    String res = Arrays.asList(s.split(wordDelimeter.toString())).stream()
          .filter(st -> !st.isEmpty())
          .map(st -> st.toLowerCase())
          .map(st -> st.substring(0, 1).toUpperCase().concat(st.substring(1)))
          .collect(Collectors.joining(wordDelimeter.toString()));

    System.out.println(s);
    System.out.println(res);

The output is

HELLO, capitalized worlD! i am here!     
Hello, Capitalized World! I Am Here!

Upvotes: 0

Kevin Cruijssen
Kevin Cruijssen

Reputation: 9336

Easier would be to use existing libraries: WordUtils.capitalize(str) (from apache commons-lang).


To fix your current code however, a possible solution would be to use a regex for words (\\w) and a combination of StringBuffer/StringBuilder setCharAt and Character.toUpperCase:

public static void main(String[] args) {
    String test = "test test   test";

    StringBuffer sb = new StringBuffer(test);
    Pattern p = Pattern.compile("\\s+\\w"); // Matches 1 or more spaces followed by 1 word
    Matcher m = p.matcher(sb);

    // Since the sentence doesn't always start with a space, we have to replace the first word manually
    sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
    while (m.find()) {
      sb.setCharAt(m.end() - 1, Character.toUpperCase(sb.charAt(m.end() - 1)));
    }

    System.out.println(sb.toString());
}

Output:

Test Test   Test

Upvotes: 0

Mad Matts
Mad Matts

Reputation: 1116

Use a regex in your split split all whitespaces

String[] words = s.split("\\s+");

Upvotes: 0

Pshemo
Pshemo

Reputation: 124275

split will try to break string in each place where delimiter is found. So if you split on space and space if placed at start of the string like

" foo".split(" ")

you will get as result array which will contain two elements: empty string "" and "foo"

["", "foo"]

Now when you call "".substring(0,1) or "".substring(1) you are using index 1 which doesn't belong to that string.

So simply before you do any String modification based on indexes check if it is safe by testing string length. So check if word you are trying to modify has length grater than 0, or use something more descriptive like if(!word.isEmpty()).

Upvotes: 1

mulunehawoke
mulunehawoke

Reputation: 41

A slight modification to Capitalize first word of a sentence in a string with multiple sentences.

public static void main( String[] args ) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = reader.readLine();

    int pos = 0;
    boolean capitalize = true;
    StringBuilder sb = new StringBuilder(s);
    while (pos < sb.length()) {
        if (sb.charAt(pos) == ' ') {
            capitalize = true;
        } else if (capitalize && !Character.isWhitespace(sb.charAt(pos))) {
            sb.setCharAt(pos, Character.toUpperCase(sb.charAt(pos)));
            capitalize = false;
        }
        pos++;
    }
    System.out.println(sb.toString());
}

I would avoid using split and go with StringBuilder instead.

Upvotes: 0

Robert Kock
Robert Kock

Reputation: 6038

Instead of splitting the string, try to simply iterate over all characters within the original string, replacing all characters by its uppercase in case it's the first character of this string or if its predecessor is a space.

Upvotes: 0

Related Questions