2 00:00:00,000 --> 00:00:01,860 >> SPEAKER 1: Let's take a look at the CS50 library, 3 00:00:01,860 --> 00:00:05,190 specifically its GetInt function. 4 00:00:05,190 --> 00:00:07,820 Here we have the actual source code for GetInt. 5 00:00:07,820 --> 00:00:12,050 And notice that it's not too long, and most of it constitutes a while loop-- 6 00:00:12,050 --> 00:00:15,620 an infinite loop at that-- that only returns a value once we've actually 7 00:00:15,620 --> 00:00:17,400 gotten what we expected. 8 00:00:17,400 --> 00:00:18,700 Let's walk through it. 9 00:00:18,700 --> 00:00:21,650 >> Notice up here first, the while loop begins. 10 00:00:21,650 --> 00:00:25,390 Notice next that we have a line of code that actually calls GetString, 11 00:00:25,390 --> 00:00:29,620 and stores the return value in a variable, called line, of type string. 12 00:00:29,620 --> 00:00:31,210 We then do a bit of a sanity check. 13 00:00:31,210 --> 00:00:35,770 If line == null, then we curiously return INT_MAX. 14 00:00:35,770 --> 00:00:40,140 >> Now it turns out that INT_MAX is a special constant declared elsewhere 15 00:00:40,140 --> 00:00:44,030 that specifies the largest possible int that you can represent in a 16 00:00:44,030 --> 00:00:45,160 program like this. 17 00:00:45,160 --> 00:00:49,430 Now we've arbitrarily decided to return INT_MAX as a sentinel value of 18 00:00:49,430 --> 00:00:53,120 sorts, one that we've reserved as meaning an error has occurred. 19 00:00:53,120 --> 00:00:56,230 So the price we pay, of course, is that GetInt can apparently not 20 00:00:56,230 --> 00:01:01,440 actually return a number as large as INT_MAX, because even if it wants to, 21 00:01:01,440 --> 00:01:04,730 that return value should really be interpreted by the caller-- 22 00:01:04,730 --> 00:01:06,260 whoever's using GetInt-- 23 00:01:06,260 --> 00:01:09,340 as an error of some sort. 24 00:01:09,340 --> 00:01:13,840 >> Next, notice that I've declared an int n and a char c. 25 00:01:13,840 --> 00:01:18,030 In this next line of code, I call a function called sscanf, passing in 26 00:01:18,030 --> 00:01:18,970 four arguments. 27 00:01:18,970 --> 00:01:25,110 line, which is the string the user's typed in, "%i %c", which is a format 28 00:01:25,110 --> 00:01:28,850 string that I'm expecting the user might type, followed by the address of 29 00:01:28,850 --> 00:01:30,920 n, and the address of c. 30 00:01:30,920 --> 00:01:34,860 Now sscanf's purpose in life is indeed to scan a string looking for the 31 00:01:34,860 --> 00:01:38,700 particular format that the programmer has specified as that second argument. 32 00:01:38,700 --> 00:01:42,020 In this case, %i is in there, as is %c. 33 00:01:42,020 --> 00:01:46,700 So if sscanf encounters an int in the user's input, that int will be stored 34 00:01:46,700 --> 00:01:50,270 inside of the variable called n, because we have provided as the third 35 00:01:50,270 --> 00:01:52,810 argument to sscanf the address of n. 36 00:01:52,810 --> 00:01:56,870 Which means that sscanf can indeed go there, and update the value therein. 37 00:01:56,870 --> 00:01:59,990 >> Now, in case the user types in something more 38 00:01:59,990 --> 00:02:01,220 than one or more digits-- 39 00:02:01,220 --> 00:02:03,570 in other words, a char of some sort-- 40 00:02:03,570 --> 00:02:07,940 that second variable c, whose address we passed into sscanf as its fourth 41 00:02:07,940 --> 00:02:10,560 argument will also be populated. 42 00:02:10,560 --> 00:02:14,220 Now the upside of checking for an additional character from the user is 43 00:02:14,220 --> 00:02:17,360 that if he or she does not cooperate, and types in more than just an int, 44 00:02:17,360 --> 00:02:20,530 we'll be able to detect it in this manner, because in that case, sscanf 45 00:02:20,530 --> 00:02:24,860 is going to return 2, signifying that both of the placeholders were filled 46 00:02:24,860 --> 00:02:25,600 with values. 47 00:02:25,600 --> 00:02:30,360 But we're hoping that sscanf instead returns 1, which means the user only 48 00:02:30,360 --> 00:02:31,630 provided an int. 49 00:02:31,630 --> 00:02:34,480 >> What do we do if sscanf indeed returns 1? 50 00:02:34,480 --> 00:02:39,150 Well, we immediately free the line that the user typed in, and then we 51 00:02:39,150 --> 00:02:42,670 immediately return n, having gotten an int. 52 00:02:42,670 --> 00:02:47,180 Else, if sscanf does not return 1, and the user therefore did not cooperate, 53 00:02:47,180 --> 00:02:51,470 we still free the line, but we now prompt the user to retry. 54 00:02:51,470 --> 00:02:55,390 And because we're still inside of that otherwise infinite loop, the process 55 00:02:55,390 --> 00:03:00,190 will begin again, and maybe again, and maybe again, until the user actually 56 00:03:00,190 --> 00:03:01,500 provides us an int. 57 00:03:01,500 --> 00:03:21,490