At this point in our functions work, we know how to write functions that return data from the function and functions that take information into the function through parameters. In this lecture, we'll write a function that gets valid user input. Here's the problem we're trying to solve. We need to get valid user input all the time and if we don't use functions, what we end up doing is we write a chunk of "get valid user input" code that looks virtually identical to all the other chunks of "get valid user input" code that we've written. We are reusing our code but we're reusing our code by copying and pasting. And that's in general a horrible programming practice. We know that functions are reusable chunks of code, so our solution to needing to do this time and time again is to use a function. Let's go do that. To start us off, I've added some comments here in the main function. I've provided a function prototype for our average score array function that we wrote last time and I've provided a prototype for a new function that we're going to use this time to get valid input. And this will get valid integer input. So I've called it getValidInteger. And it returns an int. If you think about how we've done input validation in the past, we actually need four pieces of information to do that. We have the prompt string where we ask the user to provide some input and of course that's a string or an array of characters. We have an error string that we print out if the user hasn't provided us with valid input. We have a lower bound and an upper bound for valid input. So we know that a general purpose function will need to have those four pieces of information to be able to do proper input validation. Let's go down to the actual function. Which is of course empty because we're going to build it together. The first thing I'm going to do is I'm going to declare a temporary variable that we'll use to hold the input that the user provides. And now I'll say prompt for and get input. As we know we printf to prompt, but instead of putting a string literal here, we'll just say use the prompt string that was provided as a parameter for us to print out as our prompt. We'll use scanf as usual. And we provide the address of the input local variable that we use just declared above. Now, we'll validate input. And we know we typically do this with a while loop because we don't know how many times the user might make a mistake accidentally or deliberately. So this is a while loop. So while the input is less than lower bound or the input is greater than upper bound, We know we have invalid input. Let's print a blank line before we print our error message. And now we'll print our error message. And that's just the errorstring parameter that was passed in to the function. We've been adding another space between the error string and the reprompt. And I've realized that I'm writing a big chunk of code here so I'll add a comment, print error message and get new input. And then l need to print the prompt string and read in the user's new input. When l get here in the function, because of the while loop has stopped executing, l know that l have valid input from the user. So I will just return input from the function. As you can see, we've used our typical input validation pattern here in our function. But because we wrote it as a function with these four parameters, we can use this function to get any valid integer input we want no matter what the caller of the function is going to use that input for. Let's see that in action. First thing I want to do is get the number of scores that the user wants to enter. So I'll call that n and here's where I'll just call getValidInteger. And remember, I need to pass in four arguments here when I call the function. The first one is the prompt string. So I'll say How many scores do you want to enter. And I'll give them a range, I'll say 1 to 10. We don't want to do this all day. So there's my prompt string. I need an error string. Number of scores must be between 1 and 10. And I'll be angry with them with an exclamation point and I'll provide the lower bound, 1, and the upper bound, 10. Let's write a debugging line of code that we'll get rid of soon but we'll use it to verify that we're getting an appropriate response from the function we just wrote. So I'll just say printf. N is %d and it will be the n that was returned from the function. Let's go ahead and run. I'll first show that the error checking works. So 0, no good. 11, no good. And we'll finally enter 2, and we find that n is 2 from our debugging code. So that's great, the function is working properly. I'll get rid of this debugging code. Now, remember, some compilers will let us do this, dynamically create an array sized with n elements. Visual Studio will not. So we use pointers to do that and this is just the standard code that we've seen before, allocating a dynamically sized array at run time. Now we need to read in the scores. I'll use a standard for loop for that. And because I'm indexing into the array I just created, I'm going to start i at 0. I less than n because we know that's how many scores they want to enter. I++, And here's where I read in a score. And I can just get a valid integer. This time my prompt will be different of course. Enter score 0 to 100. My error message will be different. Score must be between 0 and 100. My lower bound this time is 0, and my upper bound this time is 100. And I'm reusing the same exact function to get valid integers. And of course before we run, I have to fix the syntax of my for loop. Of course we separate these three pieces with semicolons, not commas. Let's try to run. So I'll enter three scores and I'll show that the error checking still works for the second time we're using the function. So -1, 101, and then I'll just enter scores of 1, 2, and 3. And I'm all done filling up the array. Now that I have uncommented this memory allocation, I'm going to uncomment the two lines of code that free up that memory and null out the scores pointer. And now I'll print the average of the scores. And let's do it to two decimal places as usual. And of course l can just call that other function that l included that we wrote last time. And recall that we pass in the array of scores. And we pass in the count of valid scores. And that count of valid scores is exactly n because that's how many scores the user entered for the array. We'll run it one more time. I'll enter three scores again, 100, 99 and 98. It was an easy test and the average scores point to f, that of course not correct because we need a percent sign here. One more time. Three scores, 100, 99, 98, and there you go. The average score is 99 as we expected. So this is huge. We've written a general purpose getValidInteger input and we've seen using that in two totally different ways here. One to get a number for how big our array needs to be and one to get a particular test score. And so we've actually reused this function multiple times for multiple purposes but it's just the same chunk of reusable code. To recap, in this lecture we wrote a reusable piece of code, a function, that gets valid user input. We limited our approach to doing that for an int, though of course you could write similar functions for other data types that you commonly need to get. And you'd only need to write them once and then you can use them as many times as you want. We also saw, again, the power of parameters because we could use this function that we wrote to get both the number of scores that the user wanted to enter and to get each score as they entered those scores.