15

For some reason my for loop is not terminating in my CapitalizeFirstSentence method. I set a breakpoint at that line and the condition (i != -1) is unmet, so the loop should terminate, but it doesn't!

It works when I use (i > 0) for the condition.

I'm not sure what's going on here.

import javax.swing.JOptionPane;

public class SentenceCapitalizer {


    //Main Method
    public static void main(String[] args) {
        String input; //creates a String to hold keyboard input

        //Prompt the user to enter a String using JOptionPane and set it equal to input
        input = JOptionPane.showInputDialog("Enter a string. ");

        //Display the new String with the first letter of each sentenced capitalized
        JOptionPane.showMessageDialog(null, CapitalizeFirstSentence(input));

        //Exit the program
        System.exit(0);
    }


    //Capitalize first letter of each sentence
    public static String CapitalizeFirstSentence(String in)
    {
        //Creates a StringBuilder object initiralized to the String argument "in"
        StringBuilder temp = new StringBuilder(in);

        //Capitalize first letter of the string if string length is > 0
        if (temp.length() > 0)
        {
            temp.setCharAt(0, Character.toUpperCase(temp.charAt(0)));
        }

        //sets i equal to index of the space, 
        //keep capitalizing first letters of each sentence (loops each time it capitlizes a letter)
        //until very end of the String
        for (int i = temp.indexOf(". ")+1; i != -1; i++)
        {
            //Checks for extra spaces and moves index to first character of next sentence
            while (i < temp.length() && temp.charAt(i) == ' ')
            {
                i++;
            }

            //Capitalize character
            temp.setCharAt(i, Character.toUpperCase(temp.charAt(i)));

            //Index the end of the sentence
            i = temp.indexOf(". ", i);
        }

        //Convert temp to a String and return our new first-sentenced-capitalized String
        return temp.toString();

    }

}
Tommy Saechao
  • 1,099
  • 4
  • 17
  • 28
  • what's that value that you supplied in `in` string variable? – SMA Jan 21 '16 at 08:28
  • 1
    Possible duplicate of [What is a debugger and how can it help me diagnose problems](http://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – Raedwald Jan 22 '16 at 10:48

2 Answers2

24

First, it is not a good idea to modify the loop-controlling variable inside a for loop - it is quite hard to read and understand such code, and is prone to errors.

Now, to your example:

for (int i = temp.indexOf(". ")+1; i != -1; i++)

This means:

  • Initialize i to temp.indexOf(". ")+1, which is always >= 0
  • Terminate if i == -1
  • After each iteration, increment i by 1

So:

  • At the start, the cycle won't terminate because the initialization always returns >= 0
  • Each iteration, the loop body will set i = temp.indexOf(". ", i);, which is >= -1
  • After each iteration, i will be incremented by 1, so it will now be >= 0
  • As i is always >= 0, it will never meet the condition i == -1 and thus will never terminate
Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
7

This line: for (int i = temp.indexOf(". ")+1; i != -1; i++) initializes i to be the result of indexOf + 1. IndexOf gives -1 if there is no hit, but you always add 1 to that during initialization, so it'll never be smaller than 0.

Using i > 0 seems perfectly fine there.

sfThomas
  • 1,895
  • 2
  • 18
  • 26