One of my problem sets requires me to take create a subroutine that will take a String variable as a parameter and return that same string except with the first letter of each word capitalized. The examples in the text use non-standard class the Professor specifically designed. I don't want to do this as I would think it makes more sense to learn with standard classes than see what else is out there. The problem I am having though is my subroutine is returning a String in all capitals. Here is my code:
import java.util.Scanner;
public class Capitalize {
static String capitalizeString(String x) {
String completedConversion = "";
for (int i=0; i < x.length(); i++) {
if (i == 0) {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion = completedConversion + ch;
i++;
}
if (Character.isLetter(i - 1)) {
char ch = x.charAt(i);
completedConversion = completedConversion + ch;
}
else {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion = completedConversion + ch;
}
}
return completedConversion;
} // End of subroutine
I have not yet added any commenting etc. but it should be pretty straightforward.
SOLVED: Using Keammoort's answer
public class Capitalize {
static String capitalizeString(String x) {
String completedConversion = "";
for (int i=0; i < x.length(); i++) {
if (i == 0) {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion = completedConversion + ch;
}
else if (!Character.isWhitespace(x.charAt(i - 1))) {
char ch = x.charAt(i);
completedConversion = completedConversion + ch;
}
else {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion = completedConversion + ch;
}
}
return completedConversion;
This part code causes problems:
if (Character.isLetter(i - 1)) {
char ch = x.charAt(i);
completedConversion = completedConversion + ch;
} else {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion = completedConversion + ch;
}
First of all method Character.isLetter()
with parameter of type int
returns true when passed parameter converted to a character (using codePoint) is a letter character. So for quite a few initial iterations you'll get a false
. If Character.isLetter()
returns false
then you're changing a leter to uppercase anyway.
I think there should be:
if (Character.isLetter(x.charAt(i - 1))) { //added getting character from input String
char ch = x.charAt(i);
completedConversion = completedConversion + ch;
} else {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion = completedConversion + ch;
}
Even better: use isWhitespace() method. It will prevent situations when a digit is inside a word (then character after digit would be uppercase too).
if (!Character.isWhitespace(x.charAt(i - 1))) {
//if previous char is not a whitespace don't change case
char ch = x.charAt(i);
completedConversion = completedConversion + ch;
} else {
//if previous char is a whitespace change to uppercase
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion = completedConversion + ch;
}
Then all characters that are right after spaces, tabs, etc. will be uppercase.
Putting all this together plus using a StringBuilder to avoid creating many temporary Strings would be:
static String capitalizeString(String x) {
StringBuilder completedConversion = new StringBuilder();
for (int i = 0; i < x.length(); i++) {
if (i == 0) {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion.append(ch);
i++;
}
if (!Character.isWhitespace(x.charAt(i - 1))) {
char ch = x.charAt(i);
completedConversion.append(ch);
} else {
char ch = x.charAt(i);
ch = Character.toUpperCase(ch);
completedConversion.append(ch);
}
}
return completedConversion.toString();
}