Sentinel Values

“Halt!  Who goes there?”  The sentinel on duty at the castle was wide awake.  Our sentinel values don’t carry weapons or defend ramparts, but they perform useful guarding tasks in our programs.  In computer science, a sentinel value is a value that would not normally occur in input and serves as a marker of the end of input.  Occasionally they can also be in a location in an array, not at the end of the data, but representing when a condition has been met.  Two examples are discussed below.

Census:  Who is the youngest in the castle?

A very common example is reading a stream of numerical input, either from user input or a file.  Often the input will be a non-negative number such as age, height, or weight. In such a case, the logical sentinel value is -1 because you cannot have an age, height, or weight of -1.

int youngest = Integer.MAX_VALUE;
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a list of ages (integers), ending in -1");
do {
  int age = scan.nextInt();
  if (age == -1) {
    break; 
  }
  if (age < youngest) {
    youngest = age;
  }
} while (scan.hasNext());
if (youngest != Integer.MAX_VALUE) {
  System.out.println("The youngest person is " + youngest + " years old!");
} else {
  System.out.println("The castle is empty!");
}

Here we have a program to find the youngest person in the castle.  The user inputs the ages separated by spaces or new lines, terminating in our sentinel value of -1.  These are read in by a do-while loop.  Here, we check for -1 in the loop body, using the keyword break to exit the loop if that is our current age.    We start by setting youngest to Integer.MAX so that any valid age will be less than the current youngest.   Next, we print out a message for the user to enter input.  Then in the loop, we check if the new age is less than our current youngest, updating the value if this is true.  Finally, below the loop, we check whether the value of youngest is still Integer.MAX_VALUE.  If not, we print out the age, otherwise, we print a message indicating the castle is empty.

You can find the full code CastleYoungest.txt and CastleYoungest.java.

We could have also used a non-number input such as a single letter instead of -1.  Either way, the sentinel designates the end of input.

Names:  Who sits at the round table and is a knight?

Another common situation in which a sentinel value is used is in a list full of names or other String objects.  A good sentinel here can be an extra new line, a tab, a specified string, or a numerical value. In the example below we’ll look at using a sentinel that is a special string.

  public static void main(String[] args) {
    try (Scanner scan = new Scanner(new File("RoundTableSentinelString.txt"))) {
      String s = "";
      while (scan.hasNext() && !s.equals("END")) {
        s = scan.nextLine();
        if (!s.equals("END")) {
          System.out.println(s);
        }
        
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }

  }

This is a pretty simple layout.  We open up a file with a scanner inside a try-catch block like usual for standard file I/O and then enter our loop.  Like other uses of sentinels for reading in values, we check for the presence of the sentinel value in the loop condition.  Here, we loop until we reach the end of the file or the word “END”.   Then we quit and exit the program.

When printed using test file RoundTableSentinelString.txt, the output should look like this:

King Arthur Pendragon
Sir Kay the seneschal
Sir Gwain
Sir Bedivere
Sir Lancelot
Sir Galahad
Sir Mordred
Sir Percival
Sir Tristan
Sir Ector

The whole class can be viewed SentinelString.txt and SentinelString.java  Try changing the location of the sentinel “END” in the test file to see how it works.