Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Microsoft CSharp Programming For The Absolute Beginner (2002) [eng]-1.pdf
Скачиваний:
46
Добавлен:
16.08.2013
Размер:
15.71 Mб
Скачать

Figure 4.7: The Song program re−creates the song This Old Man.

Creating a Menu

Menus are a mainstay of console−based programming and a great place to practice your method−building skills. You can begin to build the Critter program by building the menu structure for it. In Figure 4.8, you can see the output of the Critter Menu program described in the next section.

Figure 4.8: The menu for the Critter program is a standard console menu.

Creating a Main Loop

When programmers use a method, they often refer to it as calling the method. The Main loop calls a method to display the menu and then uses a switch statement to perform various tasks, based on the results. The entire assembly is enclosed inside a while loop, so the program repeats until the user exits. This is a very common scheme for this type of program. Here’s the code for the Main() method of the Critter Menu program:

using System;

namespace CritterMenu {

///<summary>

///Critter Menu

///Build a basic menu structure

///Andy Harris, 12/13/01

///</summary>

85

class Menu {

static void Main(string[] args) { bool keepGoing = true;

int choice;

while (keepGoing){ choice = showMenu(); switch (choice){

case 0:

keepGoing = false; break;

case 1:

Console.WriteLine("you talk to the critter"); break;

case 2:

Console.WriteLine ("You have fed the critter"); break;

case 3:

Console.WriteLine("You have played with the critter"); break;

case 4:

Console.WriteLine("You have renamed the critter"); break;

default:

Console.WriteLine("That was not a valid input"); break;

} // end switch } // end while loop

}// end main

Creating the Sentry Variable

I created a boolean variable named keepGoing, which is initialized to true. The program continues to cycle until the value of keepGoing is evaluated to false. This technique has a couple advantages. First, figuring out what’s going on is easy because the variable name is closely related to the concept. Setting keepGoing to false causes the program to stop. Also, several other situations can cause the program to end. Rather than keep track of all these in the Main loop, I like to use one sentry variable. Then, any time I want to end the program, I can simply set keepGoing to false, and the next time the loop executes, the program will end.

Calling a Method

The main() method doesn’t display the menu. It sends this work to the showMenu() method, which is designed to return an integer indicating which menu item the user chose. I will describe the showMenu() function in a moment. For now, in the spirit of encapsulation, assume that it works correctly and follow the logic of the Main() method.

Trick The ability to ignore the details of a subprogram temporarily is a useful skill and very much in keeping with the ideals of encapsulation. The concept is to focus on one problem at a time. At first, you think about how the main menu logic will work. After that is functioning correctly, you think about how it will relate to the showMenu() function. You can write complex programs only by dividing them into more digestible pieces, which is one of the tasks encapsulation does for you.

86

Working with the Results

After you receive a value from the showMenu() method, you need to do something with that value. I used a switch statement to determine which course of action to take. Also, notice that I included a default clause—because users do crazy things. You have to anticipate that they will type values you aren’t asking for, and you must be able to respond to those situations.

Trick Sometimes you set up a situation and think that you know every possible outcome of a calculation or user request. Then you are tempted to skip the default clause. Don’t skip it! I’ve been surprised many times to find that something I thought was impossible occurred (usually because I didn’t anticipate a particular set of circumstances). Having a default clause that is never called beats not having it and watching your program crash when something unexpected occurs.

Writing the showMenu() Method

The remainder of the Critter Menu program is dedicated to displaying the menu. This is a very simple method:

static int showMenu(){ int input = 1; Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); Console.WriteLine();

Console.WriteLine("0) Exit"); Console.WriteLine("1) Listen to Critter"); Console.WriteLine("2) Feed Critter"); Console.WriteLine("3) Play with Critter"); Console.WriteLine("4) Rename Critter"); try {

input = Convert.ToInt32(Console.ReadLine());

}catch (FormatException) { Console.WriteLine("Incorrect input"); input = 1;

}// end try

return input;

} // end showMenu } // end class

}// end namespace

I wrote the menu to the screen and read a value from the console. However, when I tested my program, I found it easy to crash.

Getting Input from the User

The input variable is an int, and Console.ReadLine() returns a string, so I had to convert the string to an integer with Convert.ToInt32(). (If you don’t remember how this object works, review the discussion of the convert object in Chapter 2, "Branching and Operators: The Math Game.") When I ran the program a few times, I found that it worked well as long as I typed a number. If I typed a letter, the program crashed and gave an unfriendly error message to the user, as you can see in Figure 4.9.

87

Figure 4.9: This error message makes my program seem very unfriendly.

Trap You must test your programs thoroughly. Better yet, have typical users test them. You might have heard this saying: The hardest part of making things foolproof is that fools can be so ingenious. Although your users aren’t fools, they probably aren’t programmers either. They try things you might never think of, such as typing a k (or more likely, the entire line of a menu or something like “I don’t know. You choose for me”). You must anticipate these problems. Fortunately for programmers, the exception−handling features described in the next section make trapping for errors much easier than it used to be.

Handling Exceptions

Making your programs as friendly as possible to the user is important, so you must avoid situations that cause the program to crash. Fortunately, C# has a robust set of features, called exceptions, that will help you. Exceptions occur when something happens that the code doesn’t know how to handle or process. For example, if the user types a k and the convert object doesn’t know how to convert a k to an integer, it throws an exception. This is like the warning indicators on your car’s dashboard. In most cases, when your program hits an exception, it will stop running and tell the user what kind of exception occurred. Of course, the user doesn’t care about this. He or she simply wants the program to work correctly.

Fortunately, there’s an easy solution. When you are testing a program and find an exception, you can surround the part of your code that caused the error with a try { } catch { } block, as in the following code fragment:

try {

input = Convert.ToInt32(Console.ReadLine());

}catch (FormatException) { Console.WriteLine("Incorrect input"); input = 1;

}// end try

The following pseudocode is what the code means:

Try to convert the console input to an integer

If you encounter a FormatException,

Tell the user his input was incorrect

Reset the input to 1, which is definitely a legal value

Any time you encounter an exception when testing your code, consider adding an exception−handling block. The try { } clause surrounds the code you suspect will cause trouble. As in other situations that use braces, you can have as many lines of code as you want inside the

88

Соседние файлы в предмете Программирование на C++