Welcome to Lesson 14!


Learning Objectives
By the end of today's class, you should know...

  • What is a do-while loop?
  • What is the syntax of a do-while loop?
  • When do you use a do-while loop instead of a while loop?
  • How do you use loops to prevent type mismatch exception?
  • How do you use a for loop, the length method for a String and the charAt method to iterate through a String, character-by-character?
  • How do you use the substring() method for a String?
    • What does it return to you?
  • What is the problem caused by newline characters when mixing next(), nextInt() and nextDouble() with nextLine()?

Announcements

  • Quiz 5 on Thursday
    • Return Quiz 4 today
  • Next Women in Computer Science club meeting this Wednesday at 12:30pm in the ATC 203 main lab
  • Last day to drop with a W is this Friday
    • You can check your current grade on Canvas
    • Please see me with questions
Review Questions
Find a partner and answer the following question:

What will be the output of the following code:
for (int i = 0; i <= 5; i++){
        if (i % 2 == 0)
            System.out.print("$");
        else
            System.out.print("!");
    }


Do-While Loops

  • Sometimes we want to execute the body of a loop at least once and perform the loop test after the body was execute
  • In this case, we can use a do-while loop (a.k.a. do loop).
  • The structure of a do-while loop looks like this
    do {
       //statements
    } while (test); // loop test
    
  • Where:
    • statements: the statements to execute the first time and repeatedly while the test remains true
    • test: the test condition to evaluate
  • The loop test is placed after the body and executes at the end of the loop
  • The statements in the body of the loop always execute at least once

Flowchart of do-while loop:

Flowchart of working of do...while loop in C programming.

Image source.

  • One common use of a do-while loop is to validate user input
  • The following code shows an example where we force the user to enter a positive value

Example do-while Loop Used to Validate Input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package loopy;

/**
*
* @author Jennifer Parrish
*/
import java.util.Scanner;

public class Loopy {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
double value;
Scanner input = new Scanner(System.in);
do {
System.out.print("Enter a positive number: ");
value = input.nextDouble();
} while (value <= 0.0); // test condition at end
System.out.println("You entered: " + value);
}
}

When to Use do-while Statements

  • Use the do-while loop when you want to force a minimum of one iteration
  • Note that you can accomplish the same control flow with a while loop
  • However, in some cases we can save a statement by using a do-while loop

Group Activity
With a partner, answer the following questions:
  • How is the syntax of a do-while loop different from a while loop?
  • When would you use choose a do-while loop over a while loop?
  • Change the following while loop into a do-while loop:
int score, sum = 0;
System.out.print("Enter a score or 0 to quit: ");

score = input.nextInt();

while (score != 0)
{
    sum += score;
    System.out.print("Enter a score or 0 to quit: ");

    score = input.nextInt();
}
System.out.println("The sum is: " + sum);
   


Loops and Error Checking

Using Loops to Check for input mismatch

  • A problem arises if the user of a our programs enters a String when we expect a number
  • For instance, in the following, we get incorrect results if the user enters "seven"
    double value = 0.0;
    ...
    value = input.nextDouble(); //user enters "seven" not 7
    
  • The problem is that Scanner cannot convert the word "seven" into the number 7
  • When this happens the code crashes with an error message about an input mismatch exception:
  • When the program suddenly crashes, the user will be confused.
  • Also the rest of the program cannot proceed.
  • A better approach would be to anticipate the possibility of the above user error and handle it in our code.
  • We can detect the failure condition using code like the following:

            double value = 0.0;
       Scanner input = new Scanner(System.in);
       System.out.print("Enter a positive number: ");
       
       if(input.hasNextDouble()) { //Check to see if the user entered a double
           value = input.nextDouble(); //read in the double
       }
       else {
           System.out.println("Error! Please enter a number not text!");
           input.next(); //read in the String value from the user to clear it from buffer
       }

  • Depending on the expected input, we can use one of the following functions to test for input mismatch:
hasNextInt() //returns true if the user entered an int
hasNextDouble() //returns true if the user entered a double
  • Both functions will return true if the user entered the correct type and false otherwise.
  • However, there is a problem with the above approach?
    • What happens if the user enters the incorrect type more than once?
  • Let's use a loop instead!

Example Program with Input Validation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

package loopy;

/**
*
* @author Jennifer Parrish
*/
import java.util.Scanner;

public class Loopy {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
double value = 0.0;
Scanner input = new Scanner(System.in);
System.out.print("Enter a number: ");

while(!input.hasNextDouble()) { //Check to see if the user entered a double
System.out.println("Error! Please enter a number not text!");
input.nextLine(); //read in the String value from the user to clear it from buffer

System.out.print("Enter a number: "); //prompt again
}
value = input.nextDouble(); //read in the double
System.out.println("You entered " + value);
}
}
More information on hasNextDouble() and hasNextInt() methods


Activity 14.1: Scores (10 pts)

  • In this exercise we use indefinite loops to process user input and to ensure correct user input.
  • Find a partner for pair programming.
  • Open a new Eclipse project named Scores.
  • Declare two variables of type double named sumScores and nextScore and initialize the variables to 0. In addition, declare an integer variable named count and initialize it to 0. The following is the psuedocode for these steps:
    set sumScores to 0
    set nextScore to 0

    set count to 0
  • Compile your code to make sure you declared the variables correctly.

  • Now we want to use a loop to enter a series of scores. Since we do not know how many scores to enter, we use an indefinite loop like the following:

  • In addition, add a statement to display sumScores after the loop.

    Compile your code to make sure you added the loop correctly. To exit the loop you will need to enter a negative number.

  • The loop includes statements to collect the sum of the scores in the variable named sumScores. Add a statement after the loop to print sumScores to the console. When you run the program after adding this code, the output should look like:
    Enter score #1: 60
    Enter score #2: 50
    Enter score #3: 20
    Enter score #4: 99
    Enter score #5: 100
    Enter score #6: 0
    Enter score #7: 45
    Enter score #8: 86
    Enter score #9: -1

    Sum of scores: 460.0

    The loop uses the sumScores variable to accumulate scores during each repetition of the loop. 

  • We could write our indefinite loop using a do-while loop instead. Replace your current loop with the following:

  • Note that the statements inside the loop did not change, only the loop statement itself. To make sure you made the changes correctly, compile and run your code and check to see if it works the same. The difference between a while and do-while loop is that a do-while ensures the body of the loop is executed at least once. 

  • One problem with our program is the user can still enter letters instead of digits. We can prevent this error by checking input.hasNextDouble() and looping until the user enters a correct value. Replace the current if statement with the following and move the nextScore = input.nextDouble()inside of an else statement as shown below:
The completed program

  • Compile and run your program to make sure you added the changes correctly. Try entering letters instead of digits and verify you see an error message.

Enter score #1: seventy
Error! Please enter a number, not text.
Enter score #2: 79
Enter score #3: 80
Enter score #4: twenty
Error! Please enter a number, not text.
Enter score #5: Error! Please enter a number, not text.
Enter score #6: 20
Enter score #7: 0
Enter score #8: -1

Sum of scores: 179.0
  • Note that when you report the error message and ask the user to try again, the count variable gets off track. There are two approaches to fixing this problem.
    • With your partner, try to find at least one solution to this problem.
  • When finished, upload your Scores.java file to Canvas.

Strings Continued

Review: Strings Versus Characters

  • Remember that a string is a series of characters enclosed in double quotes such as:
    "Hello"  "b"  "3.14159"  "$3.95"  "My address is 378 Eastbrook Dr"
  • We can store text in a variable of type string, like:
    String firstName;             // declaration
    firstName = "Jennifer";       // assignment
    String lastName = "Parrish";  // declaration + assignment
    String fullName = firstName + " " + lastName; // concatenation (+) of 2 stings
    
  • On the other hand, a character is a single letter, number or special symbol
  • We enclose characters in a single quote, rather than a double quote, like:
    'a'   'b'   'Z'   '3'   'q'   '$'   '*'
  • Also, we can store a a single character using a variable of type char, such as:
    char letterA = 'A';
    char letterB = 'B';
    
  • By declaring a char variable or using single quotes, Java knows to treat the number as a character
  • Thus, when we print a character, we see a letter rather than a number:
    char letter = 'A';
    System.out.println(letter + 'B');
    
  • As we can see, a string is made up of characters and characters are numerical codes
  • We can use this information to work with characters and strings

Indexing a String

  • Strings have a built-in indexing system with each stored in a character sequence starting at 0 (zero)

String sport = "Basketball";


  • We can access any individual character of a String variable using the String method charAt(i)
  • The general syntax is:
    stringVariable.charAt(index);
  • Where:
    • stringVariable: the name of your string variable
    • index: the number of the character position
  • For example:
    String str = "abcdef";
    char firstLetter = str.charAt(0);
    System.out.println(""+firstLetter + str.charAt(1));
    
  • The above code displays:
    ab
  • Notice that the charAt method returns a char data type
  • What will the following print?
public static void main(String[] args) {
      String sport = "Basketball";
      System.out.println("The league: " + sport.charAt(1) + sport.charAt(7));

      System.out.println("Abbreviation for this sport: " + sport.charAt(0) + sport.charAt(6);

}


Using a For Loop to Iterate Strings
  • Recall that member method length() returns the number of characters in a string variable:
    String s = "abcdef";
    int n = s.length();
  • After we know the length, it is easy to iterate through the individual characters of a string using a counting loop:
    System.out.println("Enter a message: ");
    String msg;
    msg = input.nextLine();
    for (int i = 0; i < msg.length(); i++) {
        System.out.println("Index " + i + ": " + msg.charAt(i));
    }
    

Group Activity: Iterating Strings

  • Open a new Java project called Loopy or alter an existing one.
  • Add the following for-loop code to the main method.
    String msg = "Hello, world!";
    

    for (int i = 0; i < msg.length(); i++) {
        System.out.println("Index " + i + ": " + msg.charAt(i));
    }

    
    
  • Compile and run your code. What do you see when you compile?


The substring() Method

  • The substring(begin, end) method also uses index numbers to select part of a String:
    String greeting = "Hello, World!";
    String sub = greeting.substring(0, 4);
    System.out.println(sub); // does this print "Hell" or "Hello"?
    
  • The begin argument starts with the index number of the first character
  • The end argument is always one past the last character to extract
    H e l l o ,
    W o r l d !
    0 1 2 3 4 5 6 7 8 9 10 11 12
  • As another example, we can extract "World" using:
    String w = greeting.substring(7, 12);
    System.out.println(w);
    
  • Note from the example above that the substring() method returns a String not a char.
  • Which extracts the characters highlighted in the following diagram:
    H e l l o ,
    W o r l d !
    0 1 2 3 4 5 6 7 8 9 10 11 12
  • Note that you get a Runtime Exception (error) if you try to select an index lower than 0 or beyond the end of a string
  • For example, the code:
    char bogus = greeting.charAt(15);
    
    produces an error like:

    Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 15
            at java.lang.String.charAt(String.java:687)
            at StringMethods.main(StringMethods.java:13)


Activity 14.2: How many words in your sentence? (10 pts)

  • Let's write a program that counts the number of words in a sentence input by the user.
  • Find a partner and open up a new Java project called Words
  • Alter the block comments to contain your names and section information.
  • Next declare a String variable at the top of your program named sentence:
String sentence;
  • Welcome the user to the program with the following message:
Give me a sentence, and I will count the number of words.
  • Prompt the user to input a sentence and store the user input as the sentence variable.
    Please enter your sentence.
  • Don't forget to use input.nextLine() here to read in the entire sentence.
  • How can we determine how many words are in a sentence?
  • We need to look at the whitespace.
  • Next, we will use a for loop to scroll through the sentence looking for blank spaces. 
  • Each time we encounter a new blank space, we will add one to our total for the number of words in the sentence.
  • Create a new variable at the top of main to store our counter for the number of words in the sentence. Assign it a value of 1. Why do we want to give it an initial value of 1 not 0?
int numWords = 1;
  • Now, create a for loop to iterate through the sentence. Don't forget to use the length() method here.
for (int i = 0; i < sentence.length(); i++) {
      System.out.println(sentence.charAt(i));
}
  • Now, run your program and verify that you get the following output.



  • However, this is not the purpose of our program.
  • We want to count the number of words.
  • Remove the System.out.println() statement from your for loop.
  • Replace the System.out.print statement with an if statement to check the value of the the sentence at index i to determine if it is a blank space.

if (sentence.charAt(i) == ' ') //Why am I using == here and not equals()?

  • When we encounter a blank space, we need to add one to the numWords variable.
  • Your for loop should now look like this:

for (int i = 0; i < sentence.length(); i++) {
    if (sentence.charAt(i) == ' ') {
        numWords++; 
    }
}
  • Finally, outside of your for loop, add a statement to print out the number of words.
System.out.println("There are " + numWords + " words in \"" + sentence + "\"");

  • Your program should now look like this:
  • Let's see if we can also use the substring() method to print the individual words in the sentence.
  • Add a print statement above the for loop to print the following message:

The words in your sentence are:

  • Notice that the starting index of each word occurs at the index following the blank spaces in the sentence:
I

l
o
v
e

m
y

p
e
t
0
1
2
3
4
5
6
7
8
9
10
11
12

  • In the above example, the word "love" begins at index 2, the word "my" begins at index 7 and the word "pet" begins at index 10, one index after each blank space.
  • Also the previous word ends at the index right before each blank space.
  • We already know the location of the blank spaces due our if statement.

    if (sentence.charAt(i) == ' ')

    //i will be the index of a blank space if the condition is true

  • Now, let's put it all together to print out each word using the substring() method.
  • First, add a new variable declaration at the top of your program:

int start_index = 0;

  • Next, inside the if statement of the for loop, add a print statement like the following to print out each word:

System.out.println(sentence.substring(start_index, i));

  • Finally, beneath that print statement, let's reset the starting index for the next word in the sentence:

        start_index = i+1; //Why do we use i+1 here?

  • Try running your code. You should notice a problem here. Why does the last word not print out?
    • Hint: The last character of the sentence is a \n not a ' '.
  • Let's add one last print statement, outside the loop to print the last word:

System.out.println(sentence.substring(start_index, sentence.length()));

//why do I use sentence.length()?

  • Run it again and make sure you get the correct output:

  • Submit your program to Canvas when you are finished.
  • Your code should now look like the following:

Wrap Up

  • With your partner, answer the questions from today's learning objectives

Upcoming Assignments