College of Engineering and Computer Science Computer Science Department Computer Science 106 Computing in Engineering and Science Spring 2006 Class number: 11672 Instructor: Larry Caretto Seventh Programming Exercise Objective This exercise is designed to give you the ability to write code with user-defined functions. You should learn how to write function headers, function bodies and function prototypes. You should also learn how to transfer information into and out of functions. This information passing includes returning values by the function name and the use of pass by value and pass by reference. Background for Assignment During class, we discussed the general idea that a C++ program was a collection of functions. Previously we have had only one function, the main function, in our programs. In class, we noted that all programs have a main function because execution always starts with this function. The general form of all functions is shown below. <function type> <function name> ( <argument list> ) { } <function body> The first line of the function is called the function header. In this line, the <function type> is the data type of the value returned by the function. The <argument list> is a list of variables preceded by their data types. The argument list is the method by which we pass information from the calling program into the function. (If no information is passed into the function, we simply use parentheses with nothing in them, (), in the function header; we have already seen this with the main functions we have written.) In the normal default function operation, only the values of the variables in the calling program are passed into the function. In this case, called pass by value, any operations within the function do not affect the variables in the calling program. In an alternative approach, called pass by reference, it is possible to change the values of variables in the calling program that are passed to the function. Information is normally returned from the function to the calling program through the function name. When a calling program uses a function name in an expression, control is transferred to the function. The body of the function is executed and the function returns a value to the calling program. That value is then used in evaluating the expression that contains the function name. This value returned by the function is assigned (in the function) by a return statement. We can have functions that do not return a value; such functions are assigned the void type. When we use functions, we get the results from the functions by selecting the correct data to pass to the function. Once the function is coded and tested, we should not have to recode the function for a new application of the same function. Overview of the exercise This exercise has two tasks. Each task is related to writing a program that validates input data relating to dates and times using functions. The first task requires you to copy one function from Jacaranda (Engineering) 3333 Email: lcaretto@csun.edu Mail Code 8348 Phone: 818.677.6448 Fax: 818.677.7062 Seventh programming exercise Comp 106, L. S. Caretto, Spring 2006 Page 2 this exercise handout, and write a main program that calls this function to get valid integer input data. The second task asks you to create two new functions from pseudocode to determine the maximum number of days in a month, and to place all the input in a separate input function. The second task is really an introduction to the first programming project. The functions that you develop here will be used directly in that project. The instructions below discuss the items that you should place on the submission file for this assignment. Make sure that your name and your lab day are on the top of this file. Specific tasks Task one: A function to check input ranges for integer variables Background for the task. During class we have discussed the need to check the validity of input data. Because this task occurs so often in programming it is one that is well suited for coding as a function. A function to do this, called getValidInt, is provided below. This function has the following prototype. int getValidInt( int xMin, int xMax, string name ) The getValidInt function delivers an input prompt to the user, gets the input value from the user, and checks that input value against the minimum and maximum allowed values of the variable, provided in the function call. If the variable is out of range, the user will be informed and given the opportunity to reenter the data. Once the user enters a valid value, that value is returned in the function name, getValidInt. All the tasks described in the last paragraph are done by the code in the function. A programmer who uses this function can have a program perform all these tasks simply by calling the function with the correct arguments. The function may be called several times, with different arguments, to handle the input of several variables. This function takes three arguments; the first two are the minimum and maximum allowed values of the input variable. The third argument is a string variable that contains the name of the variable for which the user will enter the input.1 This string is used in the input prompt. For example, a date program that wants the user to enter the number of a month, which can be between 1 and 12, could use the following statement to call the getValidInt function. int month = getValidInt( 1, 12, “month” ); When the main program encounters the example statement above, control is transferred to the getValidInt function. The function arguments xMin, xMax, and name are assigned the values 1, 12, and ”month”, respectively. The function has a do-while loop in which the user is prompted to enter a value for the input variable. In the example used here (getValidInt( 1, 12, “month” )), the initial cout statement in the function (shown on the next page) would print the following line to the screen. Enter a value for month between 1 and 12: 1 The string data type is used to represent character information. Such information is commonly used in data processing programs to represent individuals’ names, addresses, etc. A string literal is a series of characters enclosed in quotation marks. So that statements like the following are valid: string name = “Larry”; string name2 = name; To use the string data type it is necessary to have the following directive, #include <string>, at the start of the program to invoke the string library. Seventh programming exercise Comp 106, L. S. Caretto, Spring 2006 Page 3 Compare this line with the code for the cout statement. Note that the values for xMin, xMax, and name which were passed in the function call are used to provide the desired input prompt. The subsequent cin statement would then read a value into the variable x, which is a local integer variable in the getValidInt function. The remaining code in the do-while loop checks to see if the user’s input is in range and requests new input from the user if it is not. Once a valid value is entered, it is returned in the function name by the final statement in the function. Code for getValidInt Function You should not have to change this code! int getValidInt( int xMin, int xMax, string name ) { // Function used to input integer data within a stated range // Example: to input a value for a variable named hour with a // range between 0 and 23 use the following statement: // int hour = getValidInt( 0, 23, “hour” ); int x; bool badData; // Input data value in this function // Bad data flag do { // Loop until user enters data in range cout << "Enter a value for " << name << " between " << xMin << " and " << xMax << ": "; cin >> x; badData = x < xMin || x > xMax; if ( badData ) { cout << "\n\nIncorrect data; you entered " << name << " = " << x << "\n" << name << " must be between " << xMin << " and " << xMax << ".\nReenter the data now.\n"; } } while ( badData ); return x; } Specific assignment for this task. Copy the getValidInt function above and paste it into your code. Write a main function that calls this function three times to input the month, day, and year for a date between January 1, 1900 and December 31, 2000. After getting the input, your main function should print output like the following: Your input date is: 10/5/1939. Copy your listing to the submission file with screen output from input attempts which show that your program rejects incorrect data and prints correct results. Your should test your program to make sure that it rejects years less than 1900 and greater than 2000, months less than 1 or greater than 12 and days less than 1 or greater than 31. You can make all these tests and get correct input in one run of the program that will have two incorrect entries for all three variables (year, month, and day) and one correct entry for each of these. Task two: Writing an input function and functions to check for leap years and to determine the maximum days in a month Although we used limits of 1 and 31 for input data on the day of a month in task one, we know that the maximum value may be 28, 29, 30, and 31, depending on the month and whether or not the year is a leap year. To check for valid input on the day of the month, then, we need a function with the following prototype: int getMaxDays( int month, int year ); Seventh programming exercise Comp 106, L. S. Caretto, Spring 2006 Page 4 A call to this function passes a value for the month number (between 1 and 12) and the year into the function as the first and second parameters, respectively; the function returns the maximum number of days in the month through the function name. The pseudocode for this function is shown below: integer function getMaxDays( input month as integer, input year as integer) if month = 4 or month = 6 or month = 9 or month = 11 return 30 as function result otherwise, if month = 2 if the year is a leap year return 29 as function result otherwise return 28 as function result otherwise return 31 as function result End of function To determine if the year is a leap year, you can use a function with the following prototype: bool leap( int year ); This function has the year as an integer input parameter and returns a value of true if the year is a leap year and a value of false if the year is not a leap year. The decision as to whether a year is or is not a leap year is based on the following rules. Years evenly divisible by four are leap years, except Years evenly divisibly by 100 are not leap years, except, Years evenly divisible by 400 are leap years. This can be implemented in C++ code in several ways. Recall that we can use the mod operator (%) to determine if one number is evenly divisible by another. The expression year % 4 == 0 will be true if year is evenly divisible by four. Similarly, year % 4 != 0 will be true if year is not evenly divisible by four. One possible pseudocode implementation of the leap( year ) function is shown below. Boolean function leap( input year as integer) If year is not evenly divisible by four return false as function result otherwise, if year is evenly divisible by 400 return true as function result otherwise, if year is evenly divisible by 100 return false as function result otherwise return true as function result End of function In a more compact approach the leap(year) function would have a single statement: return ( year % 4 == 0 ) && ( year % 100 != 0 || year % 400 == 0). Seventh programming exercise Comp 106, L. S. Caretto, Spring 2006 Page 5 A final element of this task is to provide a separate input function. Such a function is usually used in larger programs where the isolation of all inputs into a separate function makes a significant enhancement to the understanding of the code. Here, the creation of a separate input function provides you practice in organizing code into separate functions and the use of pass by reference. One possible prototype for your input function is shown below. void getInput( int& year, int& month, int& day ); This function would get the input values for the three variables shown in its argument list. The use of pass-by-reference, which is set by the ampersands (&) in the argument list, is required so that the function can change the variables that are passed to the function. Specific assignment for task two. Modify the program used in task one so that all the input (using the getValidInt function) is placed in a separate input function. Change the maximum value for the input day of the month from 31 to the result of the getMaxDays( month, year ) function. This will require you to prepare two functions (getMaxDays and leap) from the pseudocode given here and to include these in your code for this task. Although it is not required for this exercise, you can make your input for this task easier by using the following pseudocode for your main program. (This is based on the code used in exercise one, task three, which you can modify for this task.) Start loop to allow repeated user inputs. o Call a function to get inputs on month, day and year from the user. o Print the date entered by the user o Prompt the user and get the appropriate input to see if the user wants to run another case. At the end of loop for running a single set of user input data, exit the loop if the user does not want to run another case. Otherwise, continue the loop. Make sure that you have the necessary function prototypes for all the functions in your program. Remember that you can get the function prototype by simply copying the function header and adding a semicolon. For this task, as in the previous task, a valid date is one between January 1, 1900 and December 31, 2000. The submission file for this task should contain a copy of your code followed by the results for the input data sets shown below. In some of these data items, you are asked to use incorrect data to test your data validation routines. When this is done, you are given one or more incorrect values followed by a correct value. For example, in the first data set you should enter two incorrect values (1899 and 2001) for the year followed by a correct value of 1990. After entering a correct value of 2 for the month, you should then enter two incorrect values (0 and 29) for the day of the month. Your submission file should contain a listing of all the code for this task and the screen output for all the data entries in the table below. This should show that your program is giving the proper error message and allowing new input to the submission file. Don’t forget to place a statement in the main program that prints the user output to the screen once all the input values are correct. Data Set 1 2 3 4 5 Year 1899 then 2001 then 1990 2000 1900 1999 1999 Month 2 2 2 13 then 12 0 then 6 Day 0 then 29 then 28 0 then 29 29 then 28 32 then 31 31 then 30 Seventh programming exercise Comp 106, L. S. Caretto, Spring 2006 Page 6 Submission requirements Due Date: April 5. Submit a copy of the submission file with all the elements asked for in the each task above. Task one code Copy of task one output showing that code rejects both high and low values for year, month and day, as well as one correct set of data with output. Task two code Copy of screen output for task two, showing all cases (including incorrect and correct entries) for this task Turn in your printed or email submission file by 11:59 pm on the due date. Only one submission, written or email, is required.