CIT 591 Name That Number: Clarifications
Fall 2008, David Matuszek

This is an attempt to clear up some of the common misunderstandings and confusion about the current assignment.

Using the Scanner

Reading input line-by-line

Here's what a lot of people are trying to do: Read in one line from the keyboard, process that line (turning numbers into words) and print it out, then read the next line.

You can't do that. Or at least, it's way more difficult that you would expect.

The Scanner really can't tell when it's at the end of a line. All it can do is get the next token (word or number). If there isn't another token, it will sit and wait until there is one. Nothing more happens in your program until there are more tokens.

When you type things in, Eclipse waits until you hit the Enter key before it gives the input to your program. Then, if the Scanner is waiting, it can continue. But it's Eclipse that's handling the Enter key--the Scanner knows nothing about it. All the Scanner can do is get tokens.

That's why the assignment says that your output will not be in neat lines, and you shouldn't worry about it. Just read tokens, one after another, until you are done, and don't think about lines.

Knowing when to quit

The Scanner has a somewhat misleading method, hasNext(), to test whether there is another token to be read. But when you are reading from the keyboard (System.in), there is no way for the computer to know you aren't going to type in something more, so this method always returns true. The hasNext() method is intended for reading from other places, like files, where there is a definite end. Dont use this method.

That's why the assignment says to read tokens until you reach the token *end*.

Also, as pointed out in the lab, the == operator is only good for comparing primitives. To compare objects, such as Strings, you need the (built-in) Object.equals(Object) method. So your code will probably look something like this:

Read in the first token;
while (!token.equals("*end*")) {  // Remember "!" means "not"
    Process the token;
    Read in the next token;
}

Looking ahead

The assignment says, "You can use hasNextInt() to ask the scanner if the next token it will return is composed entirely of digits." Notice the word "will," which implies future tense.

This method looks ahead at the next token you are going to read, not the one you have just read. You use it to peek ahead at this next token to decide how to actually read it. If hasNextInt() returns true, you can use nextInt() to read the next token as an int, otherwise you should use next to read it as a String.

Skipping over tokens?

Every time you use next or hasNextInt(), it will read a token. Every time. There's no going back and reading the same token again.

This means that every time you use one of these methods, you should assign the token it returns to a variable, and use that variable. If you are "losing" tokens, it is because you are reading the token and not doing anything with it. Your logic is wrong. The only solution is to examine your program and figure out where you are reading a token and not processing it.

The four methods (plus run)

The assignment says, "Here are the methods you must have." What that really means is, Here are the methods you must write." My fault, that could have been clearer. Those methods aren't built in to Java, they are the heart of this assignment.

The assignment says, "You may have additional methods." (Certainly you need at least public static void main(String[] args), and it's a good idea to have void run() as well.) Methods just go one after the other, in any order, in the class.

The nameOf is the "supervisor" method. Its job is to break the number (which you read using nextInt()) up into separate digits, and to call the other three methods as needed to get words for the various parts of the number.

Digits in English have different names, depending on where they are in the number. For example, the digit 2 is called twenty when it is the ten's position, twelve if it is at the end of the number and preceded by a 1, and two everyplace else. To get these words, you are supposed to write the methods nameOfTensDigit, nameOfTeens, and nameOfDigit.

What these four required methods must do, in order to be counted as correct, is to return the String of words representing the number that they are given as a parameter. They must not call the Scanner for any additional inputs. They should not print out their results--that's better done by the method that calls them. If you print out results from within the four methods, you don't know for sure what they are returning.

Notice that none of the four methods has anything to do with reading in tokens (or printing results). Hence, this work has to be done elsewhere, possibly in main, but preferably in run. Although this is implicit in the assignment, I should have been explicit.

Specifically, I recommend that your run method:

Expected results

The word zero is used for exactly one number--the number zero. It is not used for any other number. For example, the number 2008 is two thousand eight, despite all those zeros in it.

Leading zeros don't change anything. Despite the James Bond movies, 007 is seven.

In this assignment, use the "teens" words only for the last two digits. While 1970 could be "nineteen seventy", the expected (and therefore correct) wording is one thousand nine hundred seventy.

A last word...

Read the assignment. Carefully. Do what it says, not something "like" what it says.