1 00:00:00,000 --> 00:00:07,810 2 00:00:07,810 --> 00:00:09,840 >> JASON HIRSCHHORN: Welcome, everyone, to Week 6. 3 00:00:09,840 --> 00:00:14,790 I'm happy to see you all alive and well after Quiz 0, because I know that 4 00:00:14,790 --> 00:00:15,810 was a bit rough. 5 00:00:15,810 --> 00:00:18,370 But thankfully, you all did incredibly well. 6 00:00:18,370 --> 00:00:21,680 And so that is wonderful. 7 00:00:21,680 --> 00:00:25,840 If you're in my section, I've given most of you back your quizzes already. 8 00:00:25,840 --> 00:00:28,050 >> A couple of you, I'm meeting after class. 9 00:00:28,050 --> 00:00:32,360 And if you're an extension student and you haven't received your quiz back 10 00:00:32,360 --> 00:00:35,490 yet, your TF is probably working on it and grading it, and will get it back 11 00:00:35,490 --> 00:00:36,490 to you shortly. 12 00:00:36,490 --> 00:00:39,650 So my extension students who are watching right now-- hopefully live-- 13 00:00:39,650 --> 00:00:42,880 I will get your quizzes shortly as well. 14 00:00:42,880 --> 00:00:45,670 >> Our agenda for today is as follows. 15 00:00:45,670 --> 00:00:50,170 First, we're going to go over some resources that CS50 provides to you. 16 00:00:50,170 --> 00:00:54,590 We're going to go over Quiz 0 next, and I'll answer any questions anybody 17 00:00:54,590 --> 00:00:57,360 has about particular problems. 18 00:00:57,360 --> 00:01:02,050 And then, we will be going over file I/O and problem set 5. 19 00:01:02,050 --> 00:01:07,360 Those last two topics will take up the bulk of section today. 20 00:01:07,360 --> 00:01:11,680 >> I put this list up every week as a reminder to you all, but of core 21 00:01:11,680 --> 00:01:14,650 section, we only have 90 minutes-- we aren't able to cover everything that I 22 00:01:14,650 --> 00:01:16,280 would love to cover for you guys. 23 00:01:16,280 --> 00:01:21,170 But we do have a ton of resources for you to draw upon as you get to know 24 00:01:21,170 --> 00:01:24,000 the material and work through your problem sets. 25 00:01:24,000 --> 00:01:30,810 >> A reminder that I have online a text box, set up for you to fill out if you 26 00:01:30,810 --> 00:01:33,250 have any feedback for me, both positive and 27 00:01:33,250 --> 00:01:35,180 constructive, about section. 28 00:01:35,180 --> 00:01:38,600 That URL is located right down here. 29 00:01:38,600 --> 00:01:43,250 So please, take a moment if you have any feedback, whether during section, 30 00:01:43,250 --> 00:01:48,030 or after, or after you watch the video online, to give me your feedback. 31 00:01:48,030 --> 00:01:52,100 I really appreciate any and all of it. 32 00:01:52,100 --> 00:01:55,730 >> So I've been having small conversations with a lot of my 33 00:01:55,730 --> 00:01:59,350 students throughout the week-- as I hand back quizzes, talking about the 34 00:01:59,350 --> 00:02:01,480 course, seeing how you're doing. 35 00:02:01,480 --> 00:02:05,120 And one theme has come up over and over in talking about-- in 36 00:02:05,120 --> 00:02:05,660 particular-- 37 00:02:05,660 --> 00:02:07,710 problem sets. 38 00:02:07,710 --> 00:02:13,090 And I have encapsulated that theme on the board right now. 39 00:02:13,090 --> 00:02:16,630 >> Essentially, there's a difference between turning in something that is 40 00:02:16,630 --> 00:02:19,590 done correctly and something that is done well. 41 00:02:19,590 --> 00:02:22,920 Most people have been doing fantastic in terms of correctness-- 42 00:02:22,920 --> 00:02:25,460 5's or 4's on all psets. 43 00:02:25,460 --> 00:02:27,930 Most people are getting those all of the time. 44 00:02:27,930 --> 00:02:31,150 >> However, just because you've done something right does not mean you've 45 00:02:31,150 --> 00:02:34,450 done something as elegantly, or efficiently, or as cleanly as you 46 00:02:34,450 --> 00:02:35,270 could have done it. 47 00:02:35,270 --> 00:02:36,790 And that's what the design-- 48 00:02:36,790 --> 00:02:39,230 and to a lesser degree, style-- 49 00:02:39,230 --> 00:02:40,450 axes are for. 50 00:02:40,450 --> 00:02:45,130 So I am pushing you all, and other TFs are pushing you guys, to not only turn 51 00:02:45,130 --> 00:02:48,320 in things that are correct, but turn in the things that are coded well. 52 00:02:48,320 --> 00:02:53,060 >> Not doing unnecessary FOR loops, not recalculating variables if 53 00:02:53,060 --> 00:02:53,800 you don't have to. 54 00:02:53,800 --> 00:02:58,520 For example, looking back to problem set 4, when placing the bricks on the 55 00:02:58,520 --> 00:03:03,070 screen, every row-- every brick in a given row has the same y-coordinate-- 56 00:03:03,070 --> 00:03:04,390 the same height coordinate. 57 00:03:04,390 --> 00:03:07,930 >> So that y-coordinate did not need to be calculated inside the interior 58 00:03:07,930 --> 00:03:11,070 nested FOR loop that you likely used to put those bricks on the screen. 59 00:03:11,070 --> 00:03:14,030 It only needs to be calculated every time you switched a row, or 60 00:03:14,030 --> 00:03:15,200 moved down a row. 61 00:03:15,200 --> 00:03:19,760 So say if there are 10 bricks in a row, each brick can have the same 62 00:03:19,760 --> 00:03:22,260 y-coordinate, and that y-coordinate can just be calculated 63 00:03:22,260 --> 00:03:23,550 once for all of those. 64 00:03:23,550 --> 00:03:27,810 >> It does not need to be calculated 10 times, nor does that calculation need 65 00:03:27,810 --> 00:03:30,220 to happen in the actual function call-- 66 00:03:30,220 --> 00:03:33,020 the new gracked function call. 67 00:03:33,020 --> 00:03:37,820 So if that was a little confusing for you, more generically, things that 68 00:03:37,820 --> 00:03:40,730 don't need to happen every single time you go through a FOR loop shouldn't be 69 00:03:40,730 --> 00:03:42,900 put inside the FOR loop, and shouldn't happen every time you go 70 00:03:42,900 --> 00:03:44,080 through the FOR loop. 71 00:03:44,080 --> 00:03:49,270 >> Another good design example we saw in Week 3 for 15, you could keep 72 00:03:49,270 --> 00:03:50,500 track of the zero. 73 00:03:50,500 --> 00:03:53,600 So when you initialize the board, you save-- in a global variable, perhaps-- 74 00:03:53,600 --> 00:03:56,140 the x and y-coordinate of the zero. 75 00:03:56,140 --> 00:03:57,520 And then whenever you-- 76 00:03:57,520 --> 00:04:00,310 in your move function, whenever you make a successful move, you update the 77 00:04:00,310 --> 00:04:02,040 location of the zero. 78 00:04:02,040 --> 00:04:06,240 >> That would save you from having to do nested FOR loops to look through the 79 00:04:06,240 --> 00:04:10,700 board every time in your move function and find the zero, or find the tile, 80 00:04:10,700 --> 00:04:12,460 and then check what's next to it. 81 00:04:12,460 --> 00:04:16,329 Instead, you have the location of the zero, you can just look above, below, 82 00:04:16,329 --> 00:04:21,160 and to the left and right of it, to find the tile you were looking for. 83 00:04:21,160 --> 00:04:24,970 >> So in terms of the programs we're writing, they're never large enough 84 00:04:24,970 --> 00:04:28,580 that some of these design decisions are really going to hamper your 85 00:04:28,580 --> 00:04:31,670 program, or make it run more slowly, or perhaps even run out of memory. 86 00:04:31,670 --> 00:04:35,030 But we're still pushing you guys to write as elegant and 87 00:04:35,030 --> 00:04:36,450 efficient code as possible. 88 00:04:36,450 --> 00:04:39,910 >> So if you do end up writing things that have a significantly larger 89 00:04:39,910 --> 00:04:44,660 scope, they will be written with good design in addition to being correct. 90 00:04:44,660 --> 00:04:46,300 So a number of you have brought that out. 91 00:04:46,300 --> 00:04:48,560 That's something we're looking for-- something we're going to continue to 92 00:04:48,560 --> 00:04:49,840 push you guys on. 93 00:04:49,840 --> 00:04:52,460 >> If you ever have any questions about the design of your program, feel free 94 00:04:52,460 --> 00:04:56,870 to reach out to me, and I'm happy to walk through your program with you, 95 00:04:56,870 --> 00:05:01,320 and point out some of the design decisions you made, and give you some 96 00:05:01,320 --> 00:05:06,240 suggestions on how to make even better design decisions. 97 00:05:06,240 --> 00:05:08,870 >> So we're going to move on to talking about Quiz 0. 98 00:05:08,870 --> 00:05:11,300 Before we do that, does anybody have any questions about what 99 00:05:11,300 --> 00:05:14,252 I've covered so far? 100 00:05:14,252 --> 00:05:21,500 >> [RUSTLING NOISE] 101 00:05:21,500 --> 00:05:22,750 >> JASON HIRSCHHORN: Seven seconds. 102 00:05:22,750 --> 00:05:23,250 OK. 103 00:05:23,250 --> 00:05:24,970 Let's talk about Quiz 0 for a bit. 104 00:05:24,970 --> 00:05:26,700 Most of you have your Quiz 0's back. 105 00:05:26,700 --> 00:05:29,820 If you don't, hopefully you remember it a bit. 106 00:05:29,820 --> 00:05:34,770 But if you've taken Quiz 0, then you also have access to the PDF online in 107 00:05:34,770 --> 00:05:35,890 the sample solutions. 108 00:05:35,890 --> 00:05:39,480 >> Does anybody have any questions before we jump into the week's material about 109 00:05:39,480 --> 00:05:41,520 a particular problem on Quiz 0-- 110 00:05:41,520 --> 00:05:44,630 why the answer is what it is? 111 00:05:44,630 --> 00:05:47,255 Is anybody confused about anything? 112 00:05:47,255 --> 00:05:50,230 Even if you got the problem right, but just would like me to explain it a bit 113 00:05:50,230 --> 00:05:52,640 more, I'm happy to do so now. 114 00:05:52,640 --> 00:05:57,800 >> So I have asked you guys to come prepared with some 115 00:05:57,800 --> 00:05:59,440 thoughts about Quiz 0. 116 00:05:59,440 --> 00:06:02,660 So who would like to get us started with a question or 117 00:06:02,660 --> 00:06:04,655 comment about Quiz 0? 118 00:06:04,655 --> 00:06:07,435 119 00:06:07,435 --> 00:06:10,410 >> [PAPER RUSTLING] 120 00:06:10,410 --> 00:06:11,470 >> JASON HIRSCHHORN: Not everybody did perfectly. 121 00:06:11,470 --> 00:06:12,720 So I know [LAUGHS] 122 00:06:12,720 --> 00:06:15,950 there have to be some questions about Quiz 0. 123 00:06:15,950 --> 00:06:27,940 124 00:06:27,940 --> 00:06:28,590 OK. 125 00:06:28,590 --> 00:06:29,210 Yes. 126 00:06:29,210 --> 00:06:29,600 Ompica. 127 00:06:29,600 --> 00:06:30,520 >> OMPICA: Number 10. 128 00:06:30,520 --> 00:06:33,560 >> JASON HIRSCHHORN: Number 10. 129 00:06:33,560 --> 00:06:35,400 Which one was number 10? 130 00:06:35,400 --> 00:06:35,840 >> OMPICA: The-- 131 00:06:35,840 --> 00:06:36,420 >> JASON HIRSCHHORN: I haven't-- 132 00:06:36,420 --> 00:06:37,670 >> OMPICA: The include-- 133 00:06:37,670 --> 00:06:40,060 134 00:06:40,060 --> 00:06:42,180 >> JASON HIRSCHHORN: Number 10 was eight to i-- writing eight to i? 135 00:06:42,180 --> 00:06:42,980 >> OMPICA: Yeah. 136 00:06:42,980 --> 00:06:43,630 >> JASON HIRSCHHORN: OK. 137 00:06:43,630 --> 00:06:47,390 So another question you could have asked was am I prescient? 138 00:06:47,390 --> 00:06:48,630 The answer is yes. 139 00:06:48,630 --> 00:06:52,060 In section before the quiz, I asked you guys to code both Sterling and 140 00:06:52,060 --> 00:06:52,980 eight to i. 141 00:06:52,980 --> 00:06:54,770 Both of them happened to appear on the quiz. 142 00:06:54,770 --> 00:06:57,510 So hopefully, you paid attention to that. 143 00:06:57,510 --> 00:07:02,520 >> And if you had, then you would have probably done well on those two. 144 00:07:02,520 --> 00:07:06,030 But eight to i, we didn't actually code it in class, but it was, again, 145 00:07:06,030 --> 00:07:07,500 asked on the quiz. 146 00:07:07,500 --> 00:07:13,270 So a couple of things to take note when coding eight to i. 147 00:07:13,270 --> 00:07:17,320 The first thing, per the question, was that you needed to check if the string 148 00:07:17,320 --> 00:07:20,300 was equal to null. 149 00:07:20,300 --> 00:07:28,060 >> A couple people tried to check later on in the program if s bracket i was-- 150 00:07:28,060 --> 00:07:30,940 so a specific character in that string-- was equal to null. 151 00:07:30,940 --> 00:07:35,600 But remember, that null is essentially-- it's good to think of 152 00:07:35,600 --> 00:07:39,100 null as a zero pointer-- a pointer to zero-- 153 00:07:39,100 --> 00:07:40,920 someplace in memory where you can never access. 154 00:07:40,920 --> 00:07:44,730 >> So if something is equal to null, you know that it hasn't been initialized, 155 00:07:44,730 --> 00:07:46,430 or there's nothing there. 156 00:07:46,430 --> 00:07:50,950 So s is a char star, s bracket i is a char. 157 00:07:50,950 --> 00:07:57,410 So it makes sense to compare s to null, but not s bracket i to null. 158 00:07:57,410 --> 00:07:59,390 But again-- so that was the first thing that you were supposed to do-- 159 00:07:59,390 --> 00:08:03,510 check to make sure that you actually got a real string. 160 00:08:03,510 --> 00:08:08,020 >> Next, you wanted to go through each character in the string. 161 00:08:08,020 --> 00:08:12,500 And so that would be like an s bracket i, for example, if i is your iterator. 162 00:08:12,500 --> 00:08:17,250 And take that character, and get its actual value. 163 00:08:17,250 --> 00:08:21,800 You have it stored as a char, but the ASCII value for zero-- 164 00:08:21,800 --> 00:08:23,010 zero as a character-- 165 00:08:23,010 --> 00:08:25,450 is not actually the integer zero. 166 00:08:25,450 --> 00:08:28,700 It's some other number that you can look up in the ASCII table. 167 00:08:28,700 --> 00:08:30,790 >> So one way to correct for that-- probably the best way to correct for 168 00:08:30,790 --> 00:08:33,760 that-- is subtract from it the character value-- 169 00:08:33,760 --> 00:08:35,140 zero as a character. 170 00:08:35,140 --> 00:08:38,490 So minus single quote, zero, another single quote. 171 00:08:38,490 --> 00:08:44,620 That will take whatever number you have as a char, and get it equal to 172 00:08:44,620 --> 00:08:46,720 the number as an actual integer. 173 00:08:46,720 --> 00:08:50,300 >> And that is very similar to the approach a lot of people took in the 174 00:08:50,300 --> 00:08:52,800 problem set 2, with Caesar and Viginere-- 175 00:08:52,800 --> 00:08:55,160 those ciphers, when you were rotating them. 176 00:08:55,160 --> 00:08:59,210 So after you have it as a number from zero to nine, then-- depending on 177 00:08:59,210 --> 00:09:02,750 where it goes in the ultimate number-- you need to multiply it 178 00:09:02,750 --> 00:09:04,120 by a power of 10. 179 00:09:04,120 --> 00:09:07,340 >> Some people moved from the back to the front, and multiplied the individual 180 00:09:07,340 --> 00:09:08,940 number by a power of 10. 181 00:09:08,940 --> 00:09:11,160 Some people moved from the front to back-- 182 00:09:11,160 --> 00:09:14,430 and so took the highest order numbers first-- 183 00:09:14,430 --> 00:09:18,190 and would save those in a global counter variable. 184 00:09:18,190 --> 00:09:20,880 And then each time through the FOR loop, multiply that giant global 185 00:09:20,880 --> 00:09:25,640 counter variable by 10, to make space for the next char. 186 00:09:25,640 --> 00:09:28,750 >> So that was a little confusing without me writing it on the board. 187 00:09:28,750 --> 00:09:31,550 But the sample solution is available to you. 188 00:09:31,550 --> 00:09:32,870 But those were the big things we were looking for. 189 00:09:32,870 --> 00:09:36,400 Also a check to make sure that each individual character was indeed a 190 00:09:36,400 --> 00:09:39,780 character between zero and nine, and not some other character, like an A, 191 00:09:39,780 --> 00:09:41,160 for example. 192 00:09:41,160 --> 00:09:43,150 >> Those were the things we were looking for in that question. 193 00:09:43,150 --> 00:09:46,510 194 00:09:46,510 --> 00:09:47,980 Does that answer your question? 195 00:09:47,980 --> 00:09:49,320 >> OMPICA: Yeah. 196 00:09:49,320 --> 00:09:50,240 >> JASON HIRSCHHORN: OK. 197 00:09:50,240 --> 00:09:53,940 Are there any other questions about Quiz 0? 198 00:09:53,940 --> 00:09:55,440 What about compiling? 199 00:09:55,440 --> 00:09:56,740 Everybody compiling right? 200 00:09:56,740 --> 00:09:58,370 No. 201 00:09:58,370 --> 00:09:58,840 There were a-- 202 00:09:58,840 --> 00:10:01,010 [LAUGHS] 203 00:10:01,010 --> 00:10:03,265 Any questions about the compilation process? 204 00:10:03,265 --> 00:10:06,050 205 00:10:06,050 --> 00:10:06,966 Wow. 206 00:10:06,966 --> 00:10:11,090 >> [PAPER RUSTLING] 207 00:10:11,090 --> 00:10:11,520 >> JASON HIRSCHHORN: Yes. 208 00:10:11,520 --> 00:10:11,700 Michael. 209 00:10:11,700 --> 00:10:14,140 >> MICHAEL: Is number 7-- random? 210 00:10:14,140 --> 00:10:16,500 >> JASON HIRSCHHORN: Number 7. 211 00:10:16,500 --> 00:10:20,670 Number 7 was get a random integer. 212 00:10:20,670 --> 00:10:21,110 Excellent. 213 00:10:21,110 --> 00:10:25,630 So you're given an integer a and an integer b, and you want a random 214 00:10:25,630 --> 00:10:28,710 integer between a and b. 215 00:10:28,710 --> 00:10:31,740 We can actually write this one on the board, because this one 216 00:10:31,740 --> 00:10:33,320 was one line of code-- 217 00:10:33,320 --> 00:10:34,390 one way to do it. 218 00:10:34,390 --> 00:10:37,810 >> So we're given drand as a function we could use. 219 00:10:37,810 --> 00:10:38,820 And what does drand-- 220 00:10:38,820 --> 00:10:40,290 assuming it's been seeded-- 221 00:10:40,290 --> 00:10:42,316 what does drand return? 222 00:10:42,316 --> 00:10:44,840 >> MICHAEL: A float between 0.0 and 1.0. 223 00:10:44,840 --> 00:10:45,530 >> JASON HIRSCHHORN: A number-- yeah. 224 00:10:45,530 --> 00:10:47,910 A number between 0 and 1. 225 00:10:47,910 --> 00:10:51,760 And so we have b and a. 226 00:10:51,760 --> 00:10:55,480 And then we have our random number between 0 and 1 given to us by drand. 227 00:10:55,480 --> 00:11:01,480 228 00:11:01,480 --> 00:11:06,630 Some people tried to put b, or b minus a, or something inside those 229 00:11:06,630 --> 00:11:07,960 parentheses. 230 00:11:07,960 --> 00:11:11,210 That would mean that they're arguments to this function. 231 00:11:11,210 --> 00:11:13,450 >> drand does not take any arguments-- like getString does 232 00:11:13,450 --> 00:11:14,330 not take any arguments. 233 00:11:14,330 --> 00:11:16,600 So it's just open paren, close paren-- and that, itself, is 234 00:11:16,600 --> 00:11:17,330 the function call. 235 00:11:17,330 --> 00:11:19,770 And that gives you a number between 0 and 1. 236 00:11:19,770 --> 00:11:22,820 Of course, we have a whole range that numbers can be in. 237 00:11:22,820 --> 00:11:28,470 >> Say, if b is 10 and a is 5, we really want a number with a range of 5. 238 00:11:28,470 --> 00:11:36,940 So the next thing we need to do is multiply this by the range b minus a. 239 00:11:36,940 --> 00:11:40,380 So assuming that's multiplied. 240 00:11:40,380 --> 00:11:42,590 And that'll give us a number within a given range. 241 00:11:42,590 --> 00:11:46,610 And that specific range being the difference between b minus a. 242 00:11:46,610 --> 00:11:50,030 >> And finally, that'll only give it from-- say the range between b minus a 243 00:11:50,030 --> 00:11:52,520 is 5, that'll give us a number from 0 to 5. 244 00:11:52,520 --> 00:11:56,000 But if a is in fact 5, we need to boost this range up to where it's 245 00:11:56,000 --> 00:12:01,380 actually supposed to be, by adding a. 246 00:12:01,380 --> 00:12:02,580 So that gets the logic right. 247 00:12:02,580 --> 00:12:03,745 And then, would you have another question? 248 00:12:03,745 --> 00:12:04,547 >> MICHAEL: No. 249 00:12:04,547 --> 00:12:06,010 I just feel really dumb right now. 250 00:12:06,010 --> 00:12:06,405 [LAUGHS] 251 00:12:06,405 --> 00:12:06,730 >> JASON HIRSCHHORN: No. 252 00:12:06,730 --> 00:12:08,640 Don't feel really dumb. 253 00:12:08,640 --> 00:12:10,560 A number of people struggled with this question. 254 00:12:10,560 --> 00:12:13,920 And then, the other question is, drand, you said, gives you a float-- 255 00:12:13,920 --> 00:12:14,940 returns a float. 256 00:12:14,940 --> 00:12:18,020 But this function actually asked for an integer to be returned. 257 00:12:18,020 --> 00:12:23,700 >> You don't need to cast this explicitly to an integer, because these 258 00:12:23,700 --> 00:12:29,090 operations will treat it as all a float-- as a floating point number. 259 00:12:29,090 --> 00:12:31,570 Like this will-- even if this is an integer, this will 260 00:12:31,570 --> 00:12:32,890 be multiplied correctly. 261 00:12:32,890 --> 00:12:34,000 All the multiplication will work. 262 00:12:34,000 --> 00:12:35,060 You don't need to cast it here. 263 00:12:35,060 --> 00:12:36,480 In fact, you shouldn't cast it. 264 00:12:36,480 --> 00:12:37,310 >> That would-- 265 00:12:37,310 --> 00:12:40,750 if you would cast a number that's between 0 and 1-- 266 00:12:40,750 --> 00:12:42,680 a random number, a floating point-- 267 00:12:42,680 --> 00:12:47,850 then it will either be only 0 or 1, so you'll lose all of that precision. 268 00:12:47,850 --> 00:12:50,120 But at the end, when you return, it automatically gets 269 00:12:50,120 --> 00:12:51,620 sent back as an integer. 270 00:12:51,620 --> 00:12:56,870 So you don't need to do that casting yourself. 271 00:12:56,870 --> 00:13:00,810 >> So this was the answer to that question, number 7. 272 00:13:00,810 --> 00:13:02,190 Any other questions on Quiz 0? 273 00:13:02,190 --> 00:13:03,300 Yeah, Annie. 274 00:13:03,300 --> 00:13:05,050 >> ANNIE: When do we use recursive-- 275 00:13:05,050 --> 00:13:07,850 when do we use iterative loops? 276 00:13:07,850 --> 00:13:10,210 >> JASON HIRSCHHORN: When do you use recursive-- so more generally, the 277 00:13:10,210 --> 00:13:14,110 pros and cons of recursion versus an iterative approach. 278 00:13:14,110 --> 00:13:17,110 Can anybody offer a pro or a con? 279 00:13:17,110 --> 00:13:19,460 Please? 280 00:13:19,460 --> 00:13:20,140 Not can anybody. 281 00:13:20,140 --> 00:13:22,526 Who can offer a pro or a con? 282 00:13:22,526 --> 00:13:26,963 >> [PAPER RUSTLING] 283 00:13:26,963 --> 00:13:29,730 >> STUDENT 1: Recursive is less coding-- less typing? 284 00:13:29,730 --> 00:13:33,170 >> JASON HIRSCHHORN: So generally, recursion especially, a function-- 285 00:13:33,170 --> 00:13:35,750 or an algorithm like merge sort-- which lends itself 286 00:13:35,750 --> 00:13:37,300 to a recursive approach-- 287 00:13:37,300 --> 00:13:40,710 might be more straightforward to code recursively. 288 00:13:40,710 --> 00:13:43,940 And just make more sense to do it recursively. 289 00:13:43,940 --> 00:13:46,230 So that would be a pro to recursion. 290 00:13:46,230 --> 00:13:46,610 Others? 291 00:13:46,610 --> 00:13:47,467 Yeah? 292 00:13:47,467 --> 00:13:49,240 >> STUDENT 2: Con to recursion-- 293 00:13:49,240 --> 00:13:50,940 It uses more memory. 294 00:13:50,940 --> 00:13:52,200 >> JASON HIRSCHHORN: So exactly right. 295 00:13:52,200 --> 00:13:55,720 A recursive function will keep adding stack frames to the stack. 296 00:13:55,720 --> 00:13:59,690 So if you're operating on a lot of numbers, and have to call this 297 00:13:59,690 --> 00:14:02,560 function a lot, then you will certainly take up more memory, while 298 00:14:02,560 --> 00:14:05,810 an iterative approach will only put one stack frame on the stack, because 299 00:14:05,810 --> 00:14:08,420 it all happens within one function. 300 00:14:08,420 --> 00:14:11,010 >> Any other pros and cons? 301 00:14:11,010 --> 00:14:11,500 Yeah. 302 00:14:11,500 --> 00:14:12,550 >> STUDENT 3: Pros for recursion. 303 00:14:12,550 --> 00:14:15,950 You don't have to determine in advance how many times the 304 00:14:15,950 --> 00:14:17,660 code had to be repeated. 305 00:14:17,660 --> 00:14:22,810 You can have a predetermined number of times that you have to iterate, then 306 00:14:22,810 --> 00:14:26,420 recursion is better, because it takes that result. 307 00:14:26,420 --> 00:14:27,780 >> JASON HIRSCHHORN: I think that's true. 308 00:14:27,780 --> 00:14:30,770 But I think in both cases you would never-- 309 00:14:30,770 --> 00:14:33,290 you would probably get some input from the user. 310 00:14:33,290 --> 00:14:35,990 Or this function would have some input that would determine how many times it 311 00:14:35,990 --> 00:14:36,730 should run. 312 00:14:36,730 --> 00:14:39,520 So generally, you wouldn't hard code-- even in an iterative approach-- how 313 00:14:39,520 --> 00:14:40,940 many times that loop should be run. 314 00:14:40,940 --> 00:14:46,100 315 00:14:46,100 --> 00:14:48,670 >> Did you have another you were thinking about, Annie? 316 00:14:48,670 --> 00:14:49,330 OK. 317 00:14:49,330 --> 00:14:51,650 So those are probably the two-- 318 00:14:51,650 --> 00:14:54,370 the biggest pro and the biggest con to a recursive versus 319 00:14:54,370 --> 00:14:57,080 an iterative approach. 320 00:14:57,080 --> 00:14:57,690 OK. 321 00:14:57,690 --> 00:14:59,465 Anything else on Quiz 0? 322 00:14:59,465 --> 00:15:08,940 323 00:15:08,940 --> 00:15:09,920 >> Let's move on. 324 00:15:09,920 --> 00:15:15,260 File I/O. There is a wonderful short this week on file I/O that hopefully 325 00:15:15,260 --> 00:15:19,270 you have watched multiple times, and admired. 326 00:15:19,270 --> 00:15:22,910 A lot of work went into that, and I've heard it is insanely helpful. 327 00:15:22,910 --> 00:15:25,740 I also included the link on this slide, in case you have not had a 328 00:15:25,740 --> 00:15:29,160 chance to watch it 10 times. 329 00:15:29,160 --> 00:15:35,280 >> So, we are going to briefly go over the major steps to opening and working 330 00:15:35,280 --> 00:15:38,400 with files, and then we are going to dive into a coding problem before 331 00:15:38,400 --> 00:15:40,400 examining the problem set. 332 00:15:40,400 --> 00:15:44,330 So again, I'm going to put this up on the screen, but I'm going to talk for 333 00:15:44,330 --> 00:15:47,630 just a minute about what we're doing here with file I/O-- 334 00:15:47,630 --> 00:15:49,090 what does that mean? 335 00:15:49,090 --> 00:15:55,280 >> That means that we can create our programs, and then have our programs 336 00:15:55,280 --> 00:16:00,370 exit, and not have made any impact on the world outside of our program. 337 00:16:00,370 --> 00:16:04,630 But when we start working with files-- both reading them in and creating 338 00:16:04,630 --> 00:16:10,460 them-- we can have some effect on the world outside of our program. 339 00:16:10,460 --> 00:16:15,440 >> Just like if Microsoft Word wasn't able to make any Word documents, then 340 00:16:15,440 --> 00:16:18,710 once Microsoft Word quit, all of your work would be gone, and it would 341 00:16:18,710 --> 00:16:19,740 really be useless. 342 00:16:19,740 --> 00:16:23,620 We do ultimately want to be able to write programs that can affect the 343 00:16:23,620 --> 00:16:31,350 world around them, both by taking in complex inputs-- in terms of files and 344 00:16:31,350 --> 00:16:37,080 via files, and also creating interesting and compelling outputs-- 345 00:16:37,080 --> 00:16:39,520 in terms of different types of files. 346 00:16:39,520 --> 00:16:43,730 >> So that is why we are starting to learn how to work with files. 347 00:16:43,730 --> 00:16:47,080 More specifically, what we do is as follows. 348 00:16:47,080 --> 00:16:47,680 It's very simple. 349 00:16:47,680 --> 00:16:51,530 There are only a couple of steps, and they are listed here on this code. 350 00:16:51,530 --> 00:16:55,130 So we're going to go through this code line by line. 351 00:16:55,130 --> 00:16:57,630 >> First, you see highlighted-- 352 00:16:57,630 --> 00:17:01,330 when you're working with a file, regardless of the type of file it is, 353 00:17:01,330 --> 00:17:02,670 you need to open it. 354 00:17:02,670 --> 00:17:05,130 And that is with a call to fopen-- 355 00:17:05,130 --> 00:17:05,950 right here. 356 00:17:05,950 --> 00:17:07,980 You include the name of the file. 357 00:17:07,980 --> 00:17:11,930 If the file is not in your directory, or the folder where this program 358 00:17:11,930 --> 00:17:15,910 lives, then you also need to include a path to where that file is. 359 00:17:15,910 --> 00:17:19,099 >> We're going to assume that this file called "text.txt"-- 360 00:17:19,099 --> 00:17:24,220 a simple text document-- is in the same folder as this program is. 361 00:17:24,220 --> 00:17:26,859 So that's another thing to keep in mind-- that if you want to open a file 362 00:17:26,859 --> 00:17:30,050 somewhere else, you actually need to include its location. 363 00:17:30,050 --> 00:17:33,520 >> Second, you can pass an argument to fopen, and that's what you want to do 364 00:17:33,520 --> 00:17:34,620 with the file. 365 00:17:34,620 --> 00:17:38,450 There are three main arguments that you're going to pass to fopen. 366 00:17:38,450 --> 00:17:40,060 Who can give me those three? 367 00:17:40,060 --> 00:17:44,960 368 00:17:44,960 --> 00:17:47,130 Who can give me one of them? 369 00:17:47,130 --> 00:17:48,130 Yes. 370 00:17:48,130 --> 00:17:50,010 >> STUDENT 4: The file name? 371 00:17:50,010 --> 00:17:50,440 >> JASON HIRSCHHORN: Sorry. 372 00:17:50,440 --> 00:17:55,490 Three main arguments you can pass as the second argument to fopen. 373 00:17:55,490 --> 00:17:57,060 You're right-- the file name is the first argument. 374 00:17:57,060 --> 00:18:01,620 But the second argument to fopen are generally three strings, and-- yes. 375 00:18:01,620 --> 00:18:02,210 Aleja. 376 00:18:02,210 --> 00:18:03,490 >> ALEJA: A for append. 377 00:18:03,490 --> 00:18:06,840 >> JASON HIRSCHHORN: A, if you want to append to a file that already exists. 378 00:18:06,840 --> 00:18:07,810 >> STUDENT 5: R for read. 379 00:18:07,810 --> 00:18:09,930 >> JASON HIRSCHHORN: R, if you want to read from a file. 380 00:18:09,930 --> 00:18:10,670 >> STUDENT 6: W for write. 381 00:18:10,670 --> 00:18:12,840 >> JASON HIRSCHHORN: And w, if you want to write to a file. 382 00:18:12,840 --> 00:18:17,570 So in this case, we're writing to the file, so we have w. 383 00:18:17,570 --> 00:18:22,360 You open it, you also have to save the file somewhere, and that's with the 384 00:18:22,360 --> 00:18:26,000 code to the left hand side of the assignment operator-- 385 00:18:26,000 --> 00:18:31,220 I'm creating a pointer to a file called, in this case, file. 386 00:18:31,220 --> 00:18:36,070 >> We are not going to worry what this all caps FILE thing is. 387 00:18:36,070 --> 00:18:40,600 Suffice it to say, it is a long stream of zeros and ones. 388 00:18:40,600 --> 00:18:44,970 And that's how we are going to operate it and understand it. 389 00:18:44,970 --> 00:18:47,300 >> The next thing we need to do-- and this is incredibly important-- 390 00:18:47,300 --> 00:18:49,070 whenever you open a file-- 391 00:18:49,070 --> 00:18:54,250 in fact, whenever you call malloc, for example, and get some memory and try 392 00:18:54,250 --> 00:18:57,980 and save it in a pointer, you always want to check to make sure that that 393 00:18:57,980 --> 00:19:00,230 function did not return null. 394 00:19:00,230 --> 00:19:05,230 >> So in this case, we are checking to make sure that we actually opened the 395 00:19:05,230 --> 00:19:10,230 file correctly, and there was no error in our program. 396 00:19:10,230 --> 00:19:15,160 Next, once we've checked to make sure that we have a working file, we can 397 00:19:15,160 --> 00:19:18,520 write to, or read from, or append to the file. 398 00:19:18,520 --> 00:19:24,270 In this case, I am simply printing one line to this file. 399 00:19:24,270 --> 00:19:25,450 >> How do I know that? 400 00:19:25,450 --> 00:19:27,990 Well, I'm using this function called fprintf. 401 00:19:27,990 --> 00:19:30,970 All of the functions you will be using when writing to, or reading from, or 402 00:19:30,970 --> 00:19:34,950 manipulating files will be similar to functions you've seen before, but 403 00:19:34,950 --> 00:19:38,420 start with the letter F, standing for file. 404 00:19:38,420 --> 00:19:43,440 And fprintf, unlike our normal print app, takes one additional argument, 405 00:19:43,440 --> 00:19:47,800 and that is the file where you want to print this line to. 406 00:19:47,800 --> 00:19:50,640 >> I don't have anything to the right of ohai. 407 00:19:50,640 --> 00:19:52,860 I don't have the third argument to printf-- 408 00:19:52,860 --> 00:19:57,030 or the second argument to printf, the third argument to fprintf, because I 409 00:19:57,030 --> 00:19:59,480 don't have any placeholders here. 410 00:19:59,480 --> 00:20:01,070 I'm not including any variables. 411 00:20:01,070 --> 00:20:06,070 But again, fprintf and all of these file functions that operate with files 412 00:20:06,070 --> 00:20:09,820 are generally going to need the file on which they're operating. 413 00:20:09,820 --> 00:20:15,960 >> Finally, the last important thing to do is to close the file, just like 414 00:20:15,960 --> 00:20:19,530 with-- whenever we malloc something, we want to free something, lest we 415 00:20:19,530 --> 00:20:22,730 have a memory leak-- we want to close our file. 416 00:20:22,730 --> 00:20:28,180 If this program exited without closing the file, odds are nothing would go 417 00:20:28,180 --> 00:20:30,050 wrong, especially if it was a small file. 418 00:20:30,050 --> 00:20:35,020 >> But it is certainly good coding style and practice to always close your file 419 00:20:35,020 --> 00:20:38,050 when you're finished using it. 420 00:20:38,050 --> 00:20:43,630 So that is the basics of file I/O. You've probably seen that before, or 421 00:20:43,630 --> 00:20:45,710 watched it in that fantastic short. 422 00:20:45,710 --> 00:20:48,410 Does anybody have any questions, before we go into some practice coding 423 00:20:48,410 --> 00:20:51,800 problems, about file I/O or the steps I just went over? 424 00:20:51,800 --> 00:21:00,198 425 00:21:00,198 --> 00:21:03,162 >> [TYPING SOUNDS] 426 00:21:03,162 --> 00:21:04,150 >> JASON HIRSCHHORN: Do you have a question, Avi? 427 00:21:04,150 --> 00:21:04,660 >> AVI: No. 428 00:21:04,660 --> 00:21:04,740 >> JASON HIRSCHHORN: OK. 429 00:21:04,740 --> 00:21:06,746 I'm going to wait another seven seconds. 430 00:21:06,746 --> 00:21:07,590 [LAUGHS] 431 00:21:07,590 --> 00:21:08,620 That's a really good tip. 432 00:21:08,620 --> 00:21:10,750 You guys just don't like asking questions. 433 00:21:10,750 --> 00:21:11,660 That's fine. 434 00:21:11,660 --> 00:21:12,330 OK. 435 00:21:12,330 --> 00:21:17,620 So our first practice problem is, we are going to duplicate the function of 436 00:21:17,620 --> 00:21:22,330 a command line tool that you probably used before-- copy-- 437 00:21:22,330 --> 00:21:23,500 the copy tool. 438 00:21:23,500 --> 00:21:28,050 If you type cp and then pass it two arguments into your terminal, you can 439 00:21:28,050 --> 00:21:28,980 copy a file. 440 00:21:28,980 --> 00:21:31,220 And that is what we are going to write right now. 441 00:21:31,220 --> 00:21:35,830 >> So again, reading off of this slide, I'd you to write a program that takes 442 00:21:35,830 --> 00:21:38,130 two and only two command-line arguments-- 443 00:21:38,130 --> 00:21:40,750 a source file and a destination file-- 444 00:21:40,750 --> 00:21:44,590 and copies the contents of the source file to the destination file 445 00:21:44,590 --> 00:21:46,960 one byte at a time. 446 00:21:46,960 --> 00:21:48,510 So that's a lot to ask for. 447 00:21:48,510 --> 00:21:52,200 >> Again, a good approach to this is to not go straight to the C code, but 448 00:21:52,200 --> 00:21:54,280 break it down into a couple of steps. 449 00:21:54,280 --> 00:21:58,400 First, think about the logic-- exactly what I'm asking you to do-- 450 00:21:58,400 --> 00:22:00,620 and understand all of the steps to this problem. 451 00:22:00,620 --> 00:22:04,410 Not in C, just in some pseudocode, or even a mental model of 452 00:22:04,410 --> 00:22:06,030 what's going on. 453 00:22:06,030 --> 00:22:10,050 >> Next, once you have the pseudocode down, figure out how the pseudocode 454 00:22:10,050 --> 00:22:14,600 maps onto tools and things we've learned to use in C. 455 00:22:14,600 --> 00:22:19,070 >> And finally, once you have all that together, you can code the problem. 456 00:22:19,070 --> 00:22:23,370 Take 5 to 10 minutes to work on this problem. 457 00:22:23,370 --> 00:22:25,800 I'll put the instructions back up in a second. 458 00:22:25,800 --> 00:22:27,990 And then we're going to go over the pseudocode, and code 459 00:22:27,990 --> 00:22:29,230 it live as a group. 460 00:22:29,230 --> 00:22:31,640 >> If you have any questions while you're working on this, feel free to raise 461 00:22:31,640 --> 00:22:34,260 your hand, and I will come around and answer them. 462 00:22:34,260 --> 00:22:37,020 463 00:22:37,020 --> 00:22:39,330 >> STUDENT 7: Can I swipe a piece of paper? 464 00:22:39,330 --> 00:22:41,537 >> JASON HIRSCHHORN: What's up? 465 00:22:41,537 --> 00:26:46,047 466 00:26:46,047 --> 00:26:48,043 >> [TYPING SOUNDS] 467 00:26:48,043 --> 00:26:48,730 >> JASON HIRSCHHORN: OK. 468 00:26:48,730 --> 00:26:51,710 Let's go over the pseudocode first, and then I'll give you a couple more 469 00:26:51,710 --> 00:26:52,960 minutes to finish coding. 470 00:26:52,960 --> 00:26:55,540 471 00:26:55,540 --> 00:26:58,650 >> Who would like to start me off with the first line of 472 00:26:58,650 --> 00:27:00,030 pseudocode for this function? 473 00:27:00,030 --> 00:27:03,330 474 00:27:03,330 --> 00:27:05,740 >> STUDENT 8: Check to make sure that you were given two files. 475 00:27:05,740 --> 00:27:06,990 >> JASON HIRSCHHORN: OK. 476 00:27:06,990 --> 00:27:21,270 477 00:27:21,270 --> 00:27:22,990 And if we're not? 478 00:27:22,990 --> 00:27:25,974 >> STUDENT 8: I would return 0. 479 00:27:25,974 --> 00:27:27,872 >> JASON HIRSCHHORN: Should we return 0? 480 00:27:27,872 --> 00:27:30,182 >> STUDENT 8: Return a-- 481 00:27:30,182 --> 00:27:30,650 blanking. 482 00:27:30,650 --> 00:27:30,850 Sorry. 483 00:27:30,850 --> 00:27:31,210 >> JASON HIRSCHHORN: Yeah. 484 00:27:31,210 --> 00:27:32,710 Probably not 0. 485 00:27:32,710 --> 00:27:34,680 Because 0 means everything was good. 486 00:27:34,680 --> 00:27:35,030 OK. 487 00:27:35,030 --> 00:27:36,730 So that's the first line of pseudocode. 488 00:27:36,730 --> 00:27:38,715 Who has the second line of pseudocode? 489 00:27:38,715 --> 00:27:40,630 >> STUDENT 9: Open both the files? 490 00:27:40,630 --> 00:27:41,880 >> JASON HIRSCHHORN: Open both files. 491 00:27:41,880 --> 00:27:49,970 492 00:27:49,970 --> 00:27:50,920 OK? 493 00:27:50,920 --> 00:27:52,850 >> STUDENT 10: Check to see if the file is NULL? 494 00:27:52,850 --> 00:28:10,906 495 00:28:10,906 --> 00:28:12,580 >> JASON HIRSCHHORN: Check to make sure neither are NULL. 496 00:28:12,580 --> 00:28:15,800 As an aside-- 497 00:28:15,800 --> 00:28:17,540 slash 0-- 498 00:28:17,540 --> 00:28:18,887 is that NULL? 499 00:28:18,887 --> 00:28:20,080 >> STUDENT 11: No. 500 00:28:20,080 --> 00:28:21,190 >> JASON HIRSCHHORN: That's not NULL. 501 00:28:21,190 --> 00:28:23,400 That is called the NULL terminator. 502 00:28:23,400 --> 00:28:25,580 It's actually spelled with only one l. 503 00:28:25,580 --> 00:28:28,580 So checking something against that-- that's actually a character-- 504 00:28:28,580 --> 00:28:31,710 so checking something against that is not the same as checking to see if it 505 00:28:31,710 --> 00:28:32,690 equals NULL. 506 00:28:32,690 --> 00:28:34,100 >> And some people-- 507 00:28:34,100 --> 00:28:36,040 on their quizzes and their problem sets-- have got the 508 00:28:36,040 --> 00:28:36,890 two of those confused. 509 00:28:36,890 --> 00:28:38,830 But the two of those are in fact different. 510 00:28:38,830 --> 00:28:40,220 One ends a string-- 511 00:28:40,220 --> 00:28:43,210 one is a pointer to 0. 512 00:28:43,210 --> 00:28:46,490 >> STUDENT 12: Why wouldn't you check to make sure that the files are not NULL 513 00:28:46,490 --> 00:28:48,670 before you open them? 514 00:28:48,670 --> 00:28:54,772 >> JASON HIRSCHHORN: So open saves something in that file. 515 00:28:54,772 --> 00:28:57,780 And if you go back here-- 516 00:28:57,780 --> 00:28:59,520 so this line-- fopen-- 517 00:28:59,520 --> 00:29:05,300 will give you an address and store that address in file if it works. 518 00:29:05,300 --> 00:29:07,650 If it doesn't work, it will store NULL-- 519 00:29:07,650 --> 00:29:08,020 >> STUDENT 12: Oh. 520 00:29:08,020 --> 00:29:08,180 OK. 521 00:29:08,180 --> 00:29:08,500 Got you. 522 00:29:08,500 --> 00:29:09,050 >> JASON HIRSCHHORN: In file. 523 00:29:09,050 --> 00:29:11,990 So you can't check for NULL before you've opened them. 524 00:29:11,990 --> 00:29:13,520 NULL means something didn't work correctly. 525 00:29:13,520 --> 00:29:18,030 526 00:29:18,030 --> 00:29:18,740 OK. 527 00:29:18,740 --> 00:29:22,590 So check to make sure neither is? 528 00:29:22,590 --> 00:29:23,200 Or are? 529 00:29:23,200 --> 00:29:23,770 What do we think? 530 00:29:23,770 --> 00:29:24,310 We'll go with that. 531 00:29:24,310 --> 00:29:24,520 >> STUDENT 13: Is. 532 00:29:24,520 --> 00:29:25,020 >> JASON HIRSCHHORN: Is? 533 00:29:25,020 --> 00:29:25,930 Neither is? 534 00:29:25,930 --> 00:29:26,350 >> STUDENT 13: Is. 535 00:29:26,350 --> 00:29:26,390 >> JASON HIRSCHHORN: OK. 536 00:29:26,390 --> 00:29:28,510 We seem to have some consensus on that. 537 00:29:28,510 --> 00:29:30,520 Neither is NULL. 538 00:29:30,520 --> 00:29:32,250 OK, next line of pseudocode. 539 00:29:32,250 --> 00:29:33,600 Who hasn't given me a line yet? 540 00:29:33,600 --> 00:29:37,350 541 00:29:37,350 --> 00:29:38,295 We will wait for you. 542 00:29:38,295 --> 00:29:39,020 Yeah. 543 00:29:39,020 --> 00:29:40,895 >> STUDENT 14: You have to read from the first file? 544 00:29:40,895 --> 00:29:42,290 >> JASON HIRSCHHORN: OK. 545 00:29:42,290 --> 00:29:46,240 >> STUDENT 14: Or we use fscanf or something like that the first file? 546 00:29:46,240 --> 00:29:50,650 >> JASON HIRSCHHORN: So we want to read from the first file and-- 547 00:29:50,650 --> 00:29:51,900 let's put that right here. 548 00:29:51,900 --> 00:30:00,600 549 00:30:00,600 --> 00:30:01,880 Read from the source file. 550 00:30:01,880 --> 00:30:05,370 And then, what do we do after we read from the source file? 551 00:30:05,370 --> 00:30:06,620 Somebody else? 552 00:30:06,620 --> 00:30:09,150 553 00:30:09,150 --> 00:30:12,190 >> STUDENT 15: Write into the destination file? 554 00:30:12,190 --> 00:30:22,080 555 00:30:22,080 --> 00:30:25,620 >> JASON HIRSCHHORN: We write to the destination file, and-- 556 00:30:25,620 --> 00:30:26,210 OK. 557 00:30:26,210 --> 00:30:30,030 What else are we missing? 558 00:30:30,030 --> 00:30:32,460 Somebody else who has not given me a line of code yet-- of pseudocode. 559 00:30:32,460 --> 00:30:33,510 Yeah. 560 00:30:33,510 --> 00:30:36,540 >> STUDENT 16: Maybe you can always check whether there's something to read for, 561 00:30:36,540 --> 00:30:37,970 like the next line? 562 00:30:37,970 --> 00:30:39,550 That are like the next line, see if it exists. 563 00:30:39,550 --> 00:30:40,660 >> [ELECTRONIC BEEP] 564 00:30:40,660 --> 00:30:41,095 >> JASON HIRSCHHORN: Oops. 565 00:30:41,095 --> 00:30:43,120 That's my journaling software. 566 00:30:43,120 --> 00:30:43,580 Yeah? 567 00:30:43,580 --> 00:30:44,960 >> STUDENT 16: Yeah. 568 00:30:44,960 --> 00:30:48,940 >> JASON HIRSCHHORN: So give it to me one more time. 569 00:30:48,940 --> 00:30:51,640 >> STUDENT 16: Check whether there's still a next line from the 570 00:30:51,640 --> 00:30:52,920 source file to read. 571 00:30:52,920 --> 00:30:53,500 >> JASON HIRSCHHORN: OK. 572 00:30:53,500 --> 00:30:56,060 So we're not reading lines-- were reading bytes here-- 573 00:30:56,060 --> 00:30:57,590 but you're correct. 574 00:30:57,590 --> 00:31:00,040 We want to read and write until there are no more bytes. 575 00:31:00,040 --> 00:31:11,430 576 00:31:11,430 --> 00:31:11,735 OK. 577 00:31:11,735 --> 00:31:16,940 And so these should really be indented a bit, because they're under there. 578 00:31:16,940 --> 00:31:17,470 Right? 579 00:31:17,470 --> 00:31:20,620 Until we're out of bytes, we're going to read from the source file and write 580 00:31:20,620 --> 00:31:22,160 to the destination file. 581 00:31:22,160 --> 00:31:24,510 >> And then, what is the last line of pseudocode? 582 00:31:24,510 --> 00:31:26,380 Someone who's not given me something yet. 583 00:31:26,380 --> 00:31:29,270 584 00:31:29,270 --> 00:31:30,260 >> STUDENT 17: Close the files? 585 00:31:30,260 --> 00:31:31,510 >> JASON HIRSCHHORN: Exactly. 586 00:31:31,510 --> 00:31:36,370 587 00:31:36,370 --> 00:31:37,450 Close the files. 588 00:31:37,450 --> 00:31:38,400 So there's our pseudocode. 589 00:31:38,400 --> 00:31:41,870 I'm going to put the pseudocode into gedit, and in a couple of minutes we 590 00:31:41,870 --> 00:31:44,626 will code this together. 591 00:31:44,626 --> 00:33:55,280 592 00:33:55,280 --> 00:33:56,000 >> OK. 593 00:33:56,000 --> 00:33:58,290 Let us get started as a group. 594 00:33:58,290 --> 00:33:59,940 Nishant, I have my new file. 595 00:33:59,940 --> 00:34:01,130 I've just opened this up. 596 00:34:01,130 --> 00:34:01,880 Untitled document 1. 597 00:34:01,880 --> 00:34:05,490 What's the first thing I should do? 598 00:34:05,490 --> 00:34:07,040 >> NISHANT: Include libraries? 599 00:34:07,040 --> 00:34:08,219 >> JASON HIRSCHHORN: OK. 600 00:34:08,219 --> 00:34:11,070 What libraries? 601 00:34:11,070 --> 00:34:17,570 >> NISHANT: Stdio.h, stdlib.h, I believe? 602 00:34:17,570 --> 00:34:18,000 >> JASON HIRSCHHORN: OK. 603 00:34:18,000 --> 00:34:21,592 What is stdlib for? 604 00:34:21,592 --> 00:34:23,010 >> NISHANT: I forgot. 605 00:34:23,010 --> 00:34:23,219 >> JASON HIRSCHHORN: OK. 606 00:34:23,219 --> 00:34:24,179 So include stdio. 607 00:34:24,179 --> 00:34:28,630 What should I do even before I start coding? 608 00:34:28,630 --> 00:34:29,710 >> NISHANT: Write a header? 609 00:34:29,710 --> 00:34:31,830 >> JASON HIRSCHHORN: How do I get it colored? 610 00:34:31,830 --> 00:34:34,060 >> [INTERPOSING VOICES] 611 00:34:34,060 --> 00:34:35,040 >> NISHANT: How do you get it colored? 612 00:34:35,040 --> 00:34:38,060 >> JASON HIRSCHHORN: How do I color coding? 613 00:34:38,060 --> 00:34:38,570 >> NISHANT: I don't know. 614 00:34:38,570 --> 00:34:38,830 Oh. 615 00:34:38,830 --> 00:34:39,389 Save. 616 00:34:39,389 --> 00:34:39,929 >> JASON HIRSCHHORN: Save. 617 00:34:39,929 --> 00:34:40,270 Yes. 618 00:34:40,270 --> 00:34:41,760 I should save it as a .c. 619 00:34:41,760 --> 00:34:46,239 So save it on the desktop as cp.c. 620 00:34:46,239 --> 00:34:47,280 Sweet. 621 00:34:47,280 --> 00:34:51,199 And if I want to get full style points, what should I 622 00:34:51,199 --> 00:34:53,085 include at the top? 623 00:34:53,085 --> 00:34:58,390 >> NISHANT: You could write your name, name of the program, and the purpose 624 00:34:58,390 --> 00:34:59,640 of the program as well? 625 00:34:59,640 --> 00:35:08,400 626 00:35:08,400 --> 00:35:10,040 >> JASON HIRSCHHORN: Looks good. 627 00:35:10,040 --> 00:35:10,470 Excellent. 628 00:35:10,470 --> 00:35:12,940 So you've started us off perfectly. 629 00:35:12,940 --> 00:35:13,720 #include-- 630 00:35:13,720 --> 00:35:15,365 we'll also write-- 631 00:35:15,365 --> 00:35:30,050 632 00:35:30,050 --> 00:35:30,870 OK. 633 00:35:30,870 --> 00:35:33,520 So I think I'm all set to go. 634 00:35:33,520 --> 00:35:38,003 Who has the first line of code for me-- or the first lines of code that 635 00:35:38,003 --> 00:35:41,280 it will take to satisfy our first comment in pseudocode? 636 00:35:41,280 --> 00:35:41,985 You. 637 00:35:41,985 --> 00:35:48,780 >> STUDENT 18: Shouldn't it be int argc, and then char* argv? 638 00:35:48,780 --> 00:35:49,490 >> JASON HIRSCHHORN: I think you're right. 639 00:35:49,490 --> 00:35:56,270 Let's change it to int main, open paren, int argc, comma, char* argv? 640 00:35:56,270 --> 00:35:57,150 Like that? 641 00:35:57,150 --> 00:35:57,410 >> STUDENT 18: Brackets. 642 00:35:57,410 --> 00:35:58,260 >> JASON HIRSCHHORN: Brackets. 643 00:35:58,260 --> 00:35:59,860 Open bracket, close bracket, close parent. 644 00:35:59,860 --> 00:36:00,240 Perfect. 645 00:36:00,240 --> 00:36:02,160 Now I can take command-line arguments. 646 00:36:02,160 --> 00:36:02,430 OK. 647 00:36:02,430 --> 00:36:04,250 Ensure we're given two files. 648 00:36:04,250 --> 00:36:07,905 You can give me that as well. 649 00:36:07,905 --> 00:36:09,180 >> STUDENT 18: If argc-- 650 00:36:09,180 --> 00:36:11,060 this one does not equal 3. 651 00:36:11,060 --> 00:36:14,360 >> JASON HIRSCHHORN: If open paren argc does not equal 3? 652 00:36:14,360 --> 00:36:16,970 >> STUDENT 18: Yeah, you return 1 or anything. 653 00:36:16,970 --> 00:36:17,460 >> JASON HIRSCHHORN: Sorry. 654 00:36:17,460 --> 00:36:19,120 >> STUDENT 18: Return 1 or anything. 655 00:36:19,120 --> 00:36:20,270 >> JASON HIRSCHHORN: Return 1. 656 00:36:20,270 --> 00:36:22,230 OK? 657 00:36:22,230 --> 00:36:22,970 Great. 658 00:36:22,970 --> 00:36:24,290 Open both files. 659 00:36:24,290 --> 00:36:26,160 Who can help me open both files? 660 00:36:26,160 --> 00:36:28,125 Who hasn't given me code yet? 661 00:36:28,125 --> 00:36:31,510 662 00:36:31,510 --> 00:36:32,320 Kurt? 663 00:36:32,320 --> 00:36:36,145 >> KURT: So all caps F-I-L-E star source. 664 00:36:36,145 --> 00:36:39,390 665 00:36:39,390 --> 00:36:40,920 >> JASON HIRSCHHORN: I'm going to take out the vowels. 666 00:36:40,920 --> 00:36:41,570 Those are cool. 667 00:36:41,570 --> 00:36:42,716 It's like Tumblr. 668 00:36:42,716 --> 00:36:44,610 >> STUDENT 18: Equals fopen-- 669 00:36:44,610 --> 00:36:46,612 >> JASON HIRSCHHORN: Equals fopen? 670 00:36:46,612 --> 00:36:49,870 >> STUDENT 18: Open paren, argv, open bracket. 671 00:36:49,870 --> 00:36:50,055 >> JASON HIRSCHHORN: Wait. 672 00:36:50,055 --> 00:36:50,240 Sorry. 673 00:36:50,240 --> 00:36:51,050 Open paren. 674 00:36:51,050 --> 00:36:51,456 OK. 675 00:36:51,456 --> 00:36:53,080 >> STUDENT 18: Yeah. 676 00:36:53,080 --> 00:36:55,110 Argv sub 1. 677 00:36:55,110 --> 00:36:55,860 >> JASON HIRSCHHORN: Sub 1? 678 00:36:55,860 --> 00:36:56,140 >> STUDENT 18: Yeah. 679 00:36:56,140 --> 00:36:58,540 Argv open bracket 1-- 680 00:36:58,540 --> 00:36:59,730 yes. 681 00:36:59,730 --> 00:37:06,470 And then comma, and then open double quote, r, double quote, 682 00:37:06,470 --> 00:37:08,250 close paren, semicolon. 683 00:37:08,250 --> 00:37:09,450 >> JASON HIRSCHHORN: Sweet. 684 00:37:09,450 --> 00:37:10,950 And what about the other one? 685 00:37:10,950 --> 00:37:16,030 >> STUDENT 18: Very similar, but instead of S-R-C, you'd call it D-S-T. 686 00:37:16,030 --> 00:37:17,060 >> JASON HIRSCHHORN: Oo! 687 00:37:17,060 --> 00:37:17,772 I like that. 688 00:37:17,772 --> 00:37:20,010 >> STUDENT 18: Just D-S-T. Yeah. 689 00:37:20,010 --> 00:37:23,057 And then argv, open bracket, 2. 690 00:37:23,057 --> 00:37:23,200 Yeah. 691 00:37:23,200 --> 00:37:26,720 And then w instead of r. 692 00:37:26,720 --> 00:37:27,620 Yeah. 693 00:37:27,620 --> 00:37:29,630 >> JASON HIRSCHHORN: Great. 694 00:37:29,630 --> 00:37:31,360 Next couple of lines. 695 00:37:31,360 --> 00:37:34,040 Also, if anybody has things to add to lines that we've done, feel free to 696 00:37:34,040 --> 00:37:35,690 add those as well. 697 00:37:35,690 --> 00:37:37,520 Check to make sure neither is NULL. 698 00:37:37,520 --> 00:37:41,450 Who can give me the code I need to satisfy that line of pseudocode? 699 00:37:41,450 --> 00:37:44,430 700 00:37:44,430 --> 00:37:45,870 Archer. 701 00:37:45,870 --> 00:37:58,645 >> ARCHER: If src equals equals NULL or dst equals equals 702 00:37:58,645 --> 00:38:04,590 NULL, then you return-- 703 00:38:04,590 --> 00:38:07,130 704 00:38:07,130 --> 00:38:07,976 >> JASON HIRSCHHORN: What? 705 00:38:07,976 --> 00:38:08,890 >> ARCHER: Return 2? 706 00:38:08,890 --> 00:38:09,760 >> JASON HIRSCHHORN: Return 2. 707 00:38:09,760 --> 00:38:14,400 So if open paren src equals equals NULL, or-- 708 00:38:14,400 --> 00:38:15,590 whatever that thing's-- pipe? 709 00:38:15,590 --> 00:38:16,346 Pipe? 710 00:38:16,346 --> 00:38:17,140 We'll call it pipe. 711 00:38:17,140 --> 00:38:22,340 Pipe, pipe, dst equals equals NULL, return 2. 712 00:38:22,340 --> 00:38:23,900 OK? 713 00:38:23,900 --> 00:38:26,060 Until we're out of bytes-- 714 00:38:26,060 --> 00:38:29,820 we sort of skipped over this step from the pseudocode part to going to here. 715 00:38:29,820 --> 00:38:31,970 >> But until we're out of bytes-- what does that sound like? 716 00:38:31,970 --> 00:38:34,680 What type of C structure-- 717 00:38:34,680 --> 00:38:36,160 but I don't use the word structure, because we're going to start using 718 00:38:36,160 --> 00:38:37,350 that in other cases-- 719 00:38:37,350 --> 00:38:39,495 but C tool does that sound like? 720 00:38:39,495 --> 00:38:39,970 >> STUDENT 19 : A loop. 721 00:38:39,970 --> 00:38:40,980 >> JASON HIRSCHHORN: A loop. 722 00:38:40,980 --> 00:38:43,060 Sounds like a loop. 723 00:38:43,060 --> 00:38:49,670 So who can give me the first line of the loop code right here? 724 00:38:49,670 --> 00:38:56,320 725 00:38:56,320 --> 00:39:01,980 You can also pick what kind of loop you want, if you give me 726 00:39:01,980 --> 00:39:03,215 this line of code. 727 00:39:03,215 --> 00:39:04,150 There are three kinds. 728 00:39:04,150 --> 00:39:06,530 You get to pick. 729 00:39:06,530 --> 00:39:08,080 I would suggest one of those. 730 00:39:08,080 --> 00:39:08,410 Avi. 731 00:39:08,410 --> 00:39:09,230 Which one do you want? 732 00:39:09,230 --> 00:39:09,960 >> AVI: FOR. 733 00:39:09,960 --> 00:39:11,460 >> JASON HIRSCHHORN: FOR. 734 00:39:11,460 --> 00:39:15,180 >> AVI: Int i equals zero. 735 00:39:15,180 --> 00:39:17,360 >> JASON HIRSCHHORN: OK. 736 00:39:17,360 --> 00:39:18,570 >> AVI: This part I'm not sure about. 737 00:39:18,570 --> 00:39:29,080 But i is less than size of star source? 738 00:39:29,080 --> 00:39:31,128 I'm not sure of that. 739 00:39:31,128 --> 00:39:32,580 >> JASON HIRSCHHORN: OK. 740 00:39:32,580 --> 00:39:35,870 >> AVI: Because you want the size of a file, right? 741 00:39:35,870 --> 00:39:41,090 >> JASON HIRSCHHORN: So this probably won't give us the size of the actual 742 00:39:41,090 --> 00:39:43,010 file in bytes. 743 00:39:43,010 --> 00:39:47,680 So what else could we do? 744 00:39:47,680 --> 00:39:48,810 What is another type of loop? 745 00:39:48,810 --> 00:39:50,180 Or should we stick with the FOR loop? 746 00:39:50,180 --> 00:39:55,350 747 00:39:55,350 --> 00:39:57,900 >> STUDENT 20: Could you do a WHILE loop? 748 00:39:57,900 --> 00:40:01,350 And then, what you'd do is you'd-- 749 00:40:01,350 --> 00:40:03,930 because we have a char* for the file. 750 00:40:03,930 --> 00:40:07,950 So if we just keep incrementing that until we'd find the NULL character at 751 00:40:07,950 --> 00:40:08,500 the end of it? 752 00:40:08,500 --> 00:40:11,130 Or no, is that not how files work? 753 00:40:11,130 --> 00:40:14,300 >> JASON HIRSCHHORN: So we can keep incrementing the char* 754 00:40:14,300 --> 00:40:16,340 until we find the NULL-- 755 00:40:16,340 --> 00:40:18,580 >> STUDENT 20: Essentially keep going character by character until we hit 756 00:40:18,580 --> 00:40:21,250 the end of the file. 757 00:40:21,250 --> 00:40:21,600 >> JASON HIRSCHHORN: Yes. 758 00:40:21,600 --> 00:40:22,560 So that's what we want to do. 759 00:40:22,560 --> 00:40:24,545 We want to keep reading, character by character, until we get to 760 00:40:24,545 --> 00:40:25,080 the end of the file. 761 00:40:25,080 --> 00:40:25,375 >> STUDENT 20: Yeah. 762 00:40:25,375 --> 00:40:25,860 Find-- 763 00:40:25,860 --> 00:40:28,540 what's the end or stop sign at the end of a text file. 764 00:40:28,540 --> 00:40:28,620 >> JASON HIRSCHHORN: OK. 765 00:40:28,620 --> 00:40:30,140 So when we get to the end of the file-- how do we know we've reached 766 00:40:30,140 --> 00:40:33,200 the end of a file? 767 00:40:33,200 --> 00:40:34,710 If I'm calling-- 768 00:40:34,710 --> 00:40:35,910 so let's step back. 769 00:40:35,910 --> 00:40:37,550 What is a function? 770 00:40:37,550 --> 00:40:39,360 Let's go to this line right here. 771 00:40:39,360 --> 00:40:40,630 Read from the source file. 772 00:40:40,630 --> 00:40:41,880 Who can give me that line of code? 773 00:40:41,880 --> 00:40:45,592 774 00:40:45,592 --> 00:40:47,590 >> STUDENT 21: Fscanf? 775 00:40:47,590 --> 00:40:49,110 >> JASON HIRSCHHORN: Fscanf. 776 00:40:49,110 --> 00:40:49,510 OK. 777 00:40:49,510 --> 00:40:52,240 What if I want to read, very specifically, one byte? 778 00:40:52,240 --> 00:40:55,012 779 00:40:55,012 --> 00:40:56,860 >> STUDENT 21: I don't know. 780 00:40:56,860 --> 00:40:57,110 >> JASON HIRSCHHORN: OK. 781 00:40:57,110 --> 00:40:59,380 Even simpler than fscanf-- what is a-- 782 00:40:59,380 --> 00:41:01,890 I want to read from a source file? 783 00:41:01,890 --> 00:41:03,720 Read from a source file. 784 00:41:03,720 --> 00:41:04,850 What is a function-- yeah. 785 00:41:04,850 --> 00:41:05,380 >> STUDENT 22: It's fread? 786 00:41:05,380 --> 00:41:06,070 >> JASON HIRSCHHORN: Fread. 787 00:41:06,070 --> 00:41:07,550 I think let's stick with that one for now. 788 00:41:07,550 --> 00:41:10,380 789 00:41:10,380 --> 00:41:13,650 What kind of arguments does fread take? 790 00:41:13,650 --> 00:41:17,410 >> STUDENT 22: Probably the file type, and then location in the file? 791 00:41:17,410 --> 00:41:19,550 >> JASON HIRSCHHORN: What can I type here to figure out what type of arguments 792 00:41:19,550 --> 00:41:20,950 fread takes? 793 00:41:20,950 --> 00:41:23,710 >> MULTIPLE STUDENTS: Man fread. 794 00:41:23,710 --> 00:41:24,740 >> JASON HIRSCHHORN: Man fread and fwrite. 795 00:41:24,740 --> 00:41:25,980 Looks like they hang out together. 796 00:41:25,980 --> 00:41:29,589 So fread takes how many arguments? 797 00:41:29,589 --> 00:41:30,920 >> STUDENT 23: Four. 798 00:41:30,920 --> 00:41:32,690 >> JASON HIRSCHHORN: It takes four arguments. 799 00:41:32,690 --> 00:41:41,100 It takes a pointer, a size, and that thing, which is weird, and some file. 800 00:41:41,100 --> 00:41:42,000 OK? 801 00:41:42,000 --> 00:41:43,990 Let's read about it right here. 802 00:41:43,990 --> 00:41:49,370 "The function fread reads n memb elements of data, each size bytes 803 00:41:49,370 --> 00:41:53,840 long, from the stream pointed to by stream, storing them at the location 804 00:41:53,840 --> 00:41:56,170 given by pointer." 805 00:41:56,170 --> 00:41:57,960 >> So four arguments. 806 00:41:57,960 --> 00:42:04,510 Why don't I just copy this, and paste it right here. 807 00:42:04,510 --> 00:42:10,060 808 00:42:10,060 --> 00:42:10,770 OK. 809 00:42:10,770 --> 00:42:13,673 So who can start filling out these arguments for me? 810 00:42:13,673 --> 00:42:15,840 Avi. 811 00:42:15,840 --> 00:42:17,720 >> AVI: Take out the void. 812 00:42:17,720 --> 00:42:20,530 Put just src. 813 00:42:20,530 --> 00:42:23,142 Take out pointer and the star. 814 00:42:23,142 --> 00:42:26,102 Put src. 815 00:42:26,102 --> 00:42:27,050 Then-- 816 00:42:27,050 --> 00:42:28,500 >> JASON HIRSCHHORN: So I'm going to stop you there, because that's incorrect. 817 00:42:28,500 --> 00:42:32,590 818 00:42:32,590 --> 00:42:34,710 You're right with src, but where should src go? 819 00:42:34,710 --> 00:42:35,960 >> [INTERPOSING VOICES] 820 00:42:35,960 --> 00:42:38,976 821 00:42:38,976 --> 00:42:41,610 >> JASON HIRSCHHORN: It should go over here. 822 00:42:41,610 --> 00:42:43,790 That's the src-- our src is a type. 823 00:42:43,790 --> 00:42:44,610 Let's look here. 824 00:42:44,610 --> 00:42:49,610 This is asking for a type FILE*, we actually usually see them like that. 825 00:42:49,610 --> 00:42:57,630 So this is asking for an argument of type FILE* called stream that is src. 826 00:42:57,630 --> 00:42:58,480 OK? 827 00:42:58,480 --> 00:43:00,410 >> What size of things do we want to read? 828 00:43:00,410 --> 00:43:03,340 I gave you this in the problem description. 829 00:43:03,340 --> 00:43:04,370 >> STUDENT 24: One byte at a time. 830 00:43:04,370 --> 00:43:05,340 >> JASON HIRSCHHORN: One byte. 831 00:43:05,340 --> 00:43:08,205 How big is a byte? 832 00:43:08,205 --> 00:43:11,642 Its size is in bytes, so what can I put right there? 833 00:43:11,642 --> 00:43:12,910 >> STUDENT 25: One. 834 00:43:12,910 --> 00:43:14,730 >> JASON HIRSCHHORN: One. 835 00:43:14,730 --> 00:43:17,020 Right. 836 00:43:17,020 --> 00:43:19,940 Its size is in unit byte, so 1 is 1 byte. 837 00:43:19,940 --> 00:43:22,284 How many do I want to read at a time. 838 00:43:22,284 --> 00:43:23,520 >> STUDENT 26: One? 839 00:43:23,520 --> 00:43:24,270 >> JASON HIRSCHHORN: One thing. 840 00:43:24,270 --> 00:43:28,540 I want to read one thing of size 1, one bite at a time. 841 00:43:28,540 --> 00:43:32,110 And where do I put it, once I read it? 842 00:43:32,110 --> 00:43:35,050 843 00:43:35,050 --> 00:43:36,510 >> STUDENT 27: Destination? 844 00:43:36,510 --> 00:43:39,270 >> JASON HIRSCHHORN: So I can't put it straight into destination. 845 00:43:39,270 --> 00:43:40,800 >> STUDENT 28: You're gonna put it into a third pointer? 846 00:43:40,800 --> 00:43:41,780 >> STUDENT 27: To the destination. 847 00:43:41,780 --> 00:43:42,270 >> JASON HIRSCHHORN: OK. 848 00:43:42,270 --> 00:43:42,630 Yeah. 849 00:43:42,630 --> 00:43:46,820 >> STUDENT 29: You can declare something to act as a temporary storage earlier. 850 00:43:46,820 --> 00:43:47,350 >> JASON HIRSCHHORN: OK. 851 00:43:47,350 --> 00:43:50,080 Give me that. 852 00:43:50,080 --> 00:43:53,930 >> STUDENT 29: Another file pointer, maybe? 853 00:43:53,930 --> 00:43:54,220 >> JASON HIRSCHHORN: OK. 854 00:43:54,220 --> 00:43:55,585 So this is void star-- 855 00:43:55,585 --> 00:43:57,750 it's a type void star, so it doesn't have to be a file pointer. 856 00:43:57,750 --> 00:44:02,520 And if I'm reading one byte, where would be a good place 857 00:44:02,520 --> 00:44:03,850 to store one byte? 858 00:44:03,850 --> 00:44:04,660 >> STUDENT 29: An array? 859 00:44:04,660 --> 00:44:05,770 >> JASON HIRSCHHORN: An array. 860 00:44:05,770 --> 00:44:07,730 OK. 861 00:44:07,730 --> 00:44:14,040 And what else is something that's just size one byte? 862 00:44:14,040 --> 00:44:16,980 863 00:44:16,980 --> 00:44:18,060 >> STUDENT 30: A char*? 864 00:44:18,060 --> 00:44:18,530 >> STUDENT 29: Yeah. 865 00:44:18,530 --> 00:44:19,880 >> JASON HIRSCHHORN: A char* is not one byte. 866 00:44:19,880 --> 00:44:20,440 >> STUDENT 29: A char. 867 00:44:20,440 --> 00:44:21,810 >> JASON HIRSCHHORN: A char is one byte. 868 00:44:21,810 --> 00:44:22,920 Right? 869 00:44:22,920 --> 00:44:26,740 So let's call this buffer is a generic name used for these things to store 870 00:44:26,740 --> 00:44:27,910 something temporarily. 871 00:44:27,910 --> 00:44:30,880 So I create a buffer. 872 00:44:30,880 --> 00:44:31,150 Right? 873 00:44:31,150 --> 00:44:32,990 But it does take a void*. 874 00:44:32,990 --> 00:44:38,660 So maybe you are right, that it should be a buffer of size 0. 875 00:44:38,660 --> 00:44:41,070 So it stores one-- 876 00:44:41,070 --> 00:44:41,280 right. 877 00:44:41,280 --> 00:44:43,560 >> Because this right here-- char buffer is a character, but 878 00:44:43,560 --> 00:44:45,110 this takes a void*-- 879 00:44:45,110 --> 00:44:45,870 a pointer. 880 00:44:45,870 --> 00:44:50,640 So I could do this and now buffer is a pointer. 881 00:44:50,640 --> 00:44:53,214 What else could I do? 882 00:44:53,214 --> 00:44:55,775 >> STUDENT 31: Put a star next to char. 883 00:44:55,775 --> 00:44:58,380 >> JASON HIRSCHHORN: I could have created it char*. 884 00:44:58,380 --> 00:45:00,216 OK. 885 00:45:00,216 --> 00:45:03,131 What's another thing I could do? 886 00:45:03,131 --> 00:45:04,050 Or let's go with this one. 887 00:45:04,050 --> 00:45:05,740 Char* buffer, so what do I put in here? 888 00:45:05,740 --> 00:45:08,290 889 00:45:08,290 --> 00:45:09,310 >> STUDENT 31: Buffer. 890 00:45:09,310 --> 00:45:10,560 >> JASON HIRSCHHORN: Buffer. 891 00:45:10,560 --> 00:45:12,640 892 00:45:12,640 --> 00:45:14,500 Buffer is a pointer to a char. 893 00:45:14,500 --> 00:45:19,480 And in that location, we're putting one byte of something we've read. 894 00:45:19,480 --> 00:45:19,980 Yeah. 895 00:45:19,980 --> 00:45:20,700 Avi. 896 00:45:20,700 --> 00:45:21,230 >> AVI: Just a quick question. 897 00:45:21,230 --> 00:45:24,440 Do you want to malloc buffer? 898 00:45:24,440 --> 00:45:25,930 >> JASON HIRSCHHORN: Who can answer that question? 899 00:45:25,930 --> 00:45:30,210 >> STUDENT 32: Well, It doesn't really point to anything right now, so-- 900 00:45:30,210 --> 00:45:32,610 >> JASON HIRSCHHORN: But do we want to malloc it? 901 00:45:32,610 --> 00:45:35,600 >> STUDENT 32: If you were to do it that way, I guess, yeah, because you'd need 902 00:45:35,600 --> 00:45:36,990 some place for it to point to. 903 00:45:36,990 --> 00:45:38,350 >> JASON HIRSCHHORN: Do we have to malloc it? 904 00:45:38,350 --> 00:45:40,580 >> STUDENT 33: If you're going to use it outside of the loop. 905 00:45:40,580 --> 00:45:42,524 >> JASON HIRSCHHORN: Are we going to use it outside of the loop? 906 00:45:42,524 --> 00:45:44,392 >> STUDENT 34: Yes. 907 00:45:44,392 --> 00:45:44,860 >> STUDENT 35: Wait. 908 00:45:44,860 --> 00:45:46,980 Do we want to declare it in the loop to beyond? 909 00:45:46,980 --> 00:45:50,100 >> JASON HIRSCHHORN: So I guess we have some pseudo WHILE loop here that we're 910 00:45:50,100 --> 00:45:51,950 trying to figure out, that we haven't gotten to yet. 911 00:45:51,950 --> 00:45:54,710 912 00:45:54,710 --> 00:45:56,010 We don't need to malloc it. 913 00:45:56,010 --> 00:45:59,310 We're operating in main, it's only going to be used inside this loop. 914 00:45:59,310 --> 00:46:00,540 It does not need to exist outside this. 915 00:46:00,540 --> 00:46:02,340 >> So it can be a local variable. 916 00:46:02,340 --> 00:46:03,925 You have a pointer to a local variable. 917 00:46:03,925 --> 00:46:07,984 918 00:46:07,984 --> 00:46:09,590 >> STUDENT 36: But it's not pointing to anything. 919 00:46:09,590 --> 00:46:11,540 >> JASON HIRSCHHORN: No, it's not initialized to anything. 920 00:46:11,540 --> 00:46:12,790 But we're not going to use it also. 921 00:46:12,790 --> 00:46:15,300 We're going to put something in it the first time we use it. 922 00:46:15,300 --> 00:46:16,580 So that seems OK. 923 00:46:16,580 --> 00:46:17,780 So we don't need malloc here. 924 00:46:17,780 --> 00:46:19,360 And I think it's OK as is. 925 00:46:19,360 --> 00:46:24,350 926 00:46:24,350 --> 00:46:25,790 OK. 927 00:46:25,790 --> 00:46:27,190 We have the fread line. 928 00:46:27,190 --> 00:46:28,490 Let's do the next line. 929 00:46:28,490 --> 00:46:32,984 >> If we want to write to a file, what is a good function to use to do that? 930 00:46:32,984 --> 00:46:33,770 >> STUDENT 37: Fwrite? 931 00:46:33,770 --> 00:46:35,140 >> STUDENT 38: Fprintf? 932 00:46:35,140 --> 00:46:36,010 >> JASON HIRSCHHORN: Fprintf is one. 933 00:46:36,010 --> 00:46:37,260 What's another one? 934 00:46:37,260 --> 00:46:37,680 >> STUDENT 39: Fwrite. 935 00:46:37,680 --> 00:46:38,510 >> JASON HIRSCHHORN: Fwrite. 936 00:46:38,510 --> 00:46:41,250 And for our purposes, fwrite, which we saw here, is 937 00:46:41,250 --> 00:46:42,500 probably the better choice. 938 00:46:42,500 --> 00:46:51,970 939 00:46:51,970 --> 00:46:53,950 It takes four arguments as well. 940 00:46:53,950 --> 00:46:57,570 Nishant, can you give me the arguments? 941 00:46:57,570 --> 00:47:00,570 >> NISHANT: The first one's going to be just buffer. 942 00:47:00,570 --> 00:47:02,210 >> JASON HIRSCHHORN: OK. 943 00:47:02,210 --> 00:47:06,752 >> NISHANT: The second one's just going to be 1. 944 00:47:06,752 --> 00:47:09,510 Third one's going to be 1. 945 00:47:09,510 --> 00:47:11,470 And the fourth one is going to be dst. 946 00:47:11,470 --> 00:47:18,010 947 00:47:18,010 --> 00:47:19,550 >> JASON HIRSCHHORN: Does anybody have any questions about that line? 948 00:47:19,550 --> 00:47:28,370 949 00:47:28,370 --> 00:47:29,130 That looks good. 950 00:47:29,130 --> 00:47:29,590 OK. 951 00:47:29,590 --> 00:47:34,250 So now it looks like the one thing we're missing-- actually, let's write 952 00:47:34,250 --> 00:47:35,090 this last line. 953 00:47:35,090 --> 00:47:36,300 Close the files. 954 00:47:36,300 --> 00:47:38,880 Who can finish us up writing these last two lines? 955 00:47:38,880 --> 00:47:39,120 Yes. 956 00:47:39,120 --> 00:47:39,850 Sorry, what's your name? 957 00:47:39,850 --> 00:47:40,580 >> LUCY: Lucy. 958 00:47:40,580 --> 00:47:41,580 >> JASON HIRSCHHORN: Lucy. 959 00:47:41,580 --> 00:47:47,560 >> LUCY: Fclose src and then fclose destination. 960 00:47:47,560 --> 00:47:52,430 >> JASON HIRSCHHORN: Fclose, open paren, src, close paren, semicolon. 961 00:47:52,430 --> 00:47:53,680 And fclose-- 962 00:47:53,680 --> 00:47:57,560 963 00:47:57,560 --> 00:47:58,090 yeah? 964 00:47:58,090 --> 00:48:01,710 >> LUCY: Open parentheses, dst and then semicolon. 965 00:48:01,710 --> 00:48:02,520 >> JASON HIRSCHHORN: Great. 966 00:48:02,520 --> 00:48:04,338 And what should I include at the end? 967 00:48:04,338 --> 00:48:05,210 >> LUCY: Return 0. 968 00:48:05,210 --> 00:48:05,570 >> JASON HIRSCHHORN: Return 0. 969 00:48:05,570 --> 00:48:06,820 Do I have to? 970 00:48:06,820 --> 00:48:10,560 971 00:48:10,560 --> 00:48:12,590 Just a question. 972 00:48:12,590 --> 00:48:14,957 Do we have to include return 0? 973 00:48:14,957 --> 00:48:16,240 >> MULTIPLE STUDENTS: No. 974 00:48:16,240 --> 00:48:16,430 >> JASON HIRSCHHORN: No. 975 00:48:16,430 --> 00:48:18,090 Main does it automatically if you get to the end. 976 00:48:18,090 --> 00:48:20,580 But I think it's nice to include it explicitly. 977 00:48:20,580 --> 00:48:23,860 Especially when we're returning other things throughout the program. 978 00:48:23,860 --> 00:48:24,810 OK. 979 00:48:24,810 --> 00:48:26,230 This is what we're missing-- 980 00:48:26,230 --> 00:48:28,520 WHILE what? 981 00:48:28,520 --> 00:48:31,630 Who can think of some-- 982 00:48:31,630 --> 00:48:35,240 has some sense of what things could go in there? 983 00:48:35,240 --> 00:48:37,350 Even if it's just in some pseudocode like language? 984 00:48:37,350 --> 00:48:41,330 >> What are we really-- what do we want to go until? 985 00:48:41,330 --> 00:48:41,980 Yeah, Lucy. 986 00:48:41,980 --> 00:48:43,240 >> LUCY: The end of file. 987 00:48:43,240 --> 00:48:44,990 >> JASON HIRSCHHORN: The end of file. 988 00:48:44,990 --> 00:48:49,280 So what do you mean by end of file? 989 00:48:49,280 --> 00:48:50,955 >> LUCY: Once you reach the end of the file, stop. 990 00:48:50,955 --> 00:48:51,240 >> JASON HIRSCHHORN: OK. 991 00:48:51,240 --> 00:48:53,460 So once we reach the end of the file. 992 00:48:53,460 --> 00:48:56,893 How do we know when we've reached the end of the file? 993 00:48:56,893 --> 00:48:59,900 >> STUDENT 40: I think buffer will be set to NULL. 994 00:48:59,900 --> 00:49:01,885 >> STUDENT 41: Buffer is declared inside the loop. 995 00:49:01,885 --> 00:49:03,670 >> JASON HIRSCHHORN: So you think buffer will be set to NULL. 996 00:49:03,670 --> 00:49:05,850 Why would buffer be set to NULL? 997 00:49:05,850 --> 00:49:10,420 >> STUDENT 40: Because when you fread, you're trying to put 998 00:49:10,420 --> 00:49:13,528 nothing into buffer. 999 00:49:13,528 --> 00:49:13,980 >> JASON HIRSCHHORN: OK. 1000 00:49:13,980 --> 00:49:15,550 So you're thinking fread-- 1001 00:49:15,550 --> 00:49:19,000 when we've reached the end of the file, what is fread going to do? 1002 00:49:19,000 --> 00:49:21,230 I think that's the question we have to figure out. 1003 00:49:21,230 --> 00:49:21,960 What does fread do? 1004 00:49:21,960 --> 00:49:25,640 Does it put NULL in buffer, or does it do something else? 1005 00:49:25,640 --> 00:49:27,510 How can we figure out what it does? 1006 00:49:27,510 --> 00:49:28,190 >> STUDENT 42: Man. 1007 00:49:28,190 --> 00:49:28,810 >> JASON HIRSCHHORN: Man. 1008 00:49:28,810 --> 00:49:32,280 So let's look over here. 1009 00:49:32,280 --> 00:49:34,000 Return value. 1010 00:49:34,000 --> 00:49:39,620 On success, fread and fwrite return the number of items read or written. 1011 00:49:39,620 --> 00:49:43,700 This number equals the number of bytes transferred only when size is 1. 1012 00:49:43,700 --> 00:49:47,780 If an error occurs, or the end of the file is reached, the return value is a 1013 00:49:47,780 --> 00:49:51,490 short item count or 0. 1014 00:49:51,490 --> 00:49:57,860 >> So for our purposes, if fread reaches the end of the file, and reads from 1015 00:49:57,860 --> 00:50:02,100 the end of file, there's nothing left to read, what's it going to return? 1016 00:50:02,100 --> 00:50:03,290 >> STUDENT 43: Zero? 1017 00:50:03,290 --> 00:50:04,540 >> JASON HIRSCHHORN: What? 1018 00:50:04,540 --> 00:50:05,300 >> STUDENT 43: Zero? 1019 00:50:05,300 --> 00:50:05,690 >> JASON HIRSCHHORN: Zero. 1020 00:50:05,690 --> 00:50:06,940 It's going to return zero. 1021 00:50:06,940 --> 00:50:09,360 1022 00:50:09,360 --> 00:50:13,010 So we know that fread, when we've reached the end of the file, is going 1023 00:50:13,010 --> 00:50:13,690 to return zero. 1024 00:50:13,690 --> 00:50:17,460 How can we use that to our advantage? 1025 00:50:17,460 --> 00:50:21,733 >> AVI: You can declare a variable outside of the loop called check. 1026 00:50:21,733 --> 00:50:27,040 If check equals-- 1027 00:50:27,040 --> 00:50:28,190 for now-- one. 1028 00:50:28,190 --> 00:50:28,920 >> JASON HIRSCHHORN: OK. 1029 00:50:28,920 --> 00:50:38,050 >> AVI: And then you can put an IF statement right after fread saying if 1030 00:50:38,050 --> 00:50:42,600 fread equals zero-- 1031 00:50:42,600 --> 00:50:43,850 no. 1032 00:50:43,850 --> 00:50:46,002 1033 00:50:46,002 --> 00:50:47,252 >> JASON HIRSCHHORN: Who can help Avi out? 1034 00:50:47,252 --> 00:50:49,690 1035 00:50:49,690 --> 00:50:52,410 >> AVI: What's the value returned by fread? 1036 00:50:52,410 --> 00:50:54,060 >> JASON HIRSCHHORN: We just went over that. 1037 00:50:54,060 --> 00:50:55,450 >> AVI: How do you represent it? 1038 00:50:55,450 --> 00:50:57,190 >> JASON HIRSCHHORN: So it returns-- let's look up here-- it returns a 1039 00:50:57,190 --> 00:50:59,340 size_t, which is essentially an integer. 1040 00:50:59,340 --> 00:51:02,240 1041 00:51:02,240 --> 00:51:03,410 So it returns an integer. 1042 00:51:03,410 --> 00:51:05,160 And in our case, it will return 1 or 0-- 1043 00:51:05,160 --> 00:51:08,760 1 if it read one thing-- one byte, and 0 if we've reached the end. 1044 00:51:08,760 --> 00:51:13,560 1045 00:51:13,560 --> 00:51:16,450 So if fread-- 1046 00:51:16,450 --> 00:51:16,855 yeah? 1047 00:51:16,855 --> 00:51:20,330 >> STUDENT 45: Can't you just put the full fread(buffer, 1, 1, src) into the 1048 00:51:20,330 --> 00:51:21,660 while loop? 1049 00:51:21,660 --> 00:51:26,510 >> JASON HIRSCHHORN: So you propose doing this into there? 1050 00:51:26,510 --> 00:51:27,600 >> [INTERPOSING VOICES] 1051 00:51:27,600 --> 00:51:29,520 >> JASON HIRSCHHORN: Hold on. 1052 00:51:29,520 --> 00:51:30,885 So we're ridding of that. 1053 00:51:30,885 --> 00:51:33,300 So you're proposing putting fread into there? 1054 00:51:33,300 --> 00:51:35,457 What should we also move if you want to do that? 1055 00:51:35,457 --> 00:51:36,740 >> STUDENT 45: The buffer outside. 1056 00:51:36,740 --> 00:51:38,110 >> JASON HIRSCHHORN: We should also move this out here. 1057 00:51:38,110 --> 00:51:41,700 >> STUDENT 45: But does that constantly move it forward? 1058 00:51:41,700 --> 00:51:42,950 >> [INTERPOSING VOICES] 1059 00:51:42,950 --> 00:51:46,540 1060 00:51:46,540 --> 00:51:47,470 >> JASON HIRSCHHORN: OK. 1061 00:51:47,470 --> 00:51:50,570 So this is what Okshar proposed. 1062 00:51:50,570 --> 00:51:51,930 We create our buffer. 1063 00:51:51,930 --> 00:51:57,020 We WHILE fread, then we fwrite. 1064 00:51:57,020 --> 00:51:59,760 Thoughts on this? 1065 00:51:59,760 --> 00:52:04,050 >> STUDENT 46: My only question is, would it actually execute the command fread? 1066 00:52:04,050 --> 00:52:06,175 >> JASON HIRSCHHORN: Great question. 1067 00:52:06,175 --> 00:52:11,050 When you're putting a function call inside of a condition, does that 1068 00:52:11,050 --> 00:52:12,300 function call execute? 1069 00:52:12,300 --> 00:52:15,760 1070 00:52:15,760 --> 00:52:17,770 We've seen examples of this before. 1071 00:52:17,770 --> 00:52:24,900 1072 00:52:24,900 --> 00:52:25,660 Right? 1073 00:52:25,660 --> 00:52:26,125 >> STUDENT 46: OK. 1074 00:52:26,125 --> 00:52:26,590 Yeah. 1075 00:52:26,590 --> 00:52:30,140 So it does execute. 1076 00:52:30,140 --> 00:52:31,790 >> JASON HIRSCHHORN: We've seen things like that before, where we have a 1077 00:52:31,790 --> 00:52:33,550 function call inside of a condition. 1078 00:52:33,550 --> 00:52:35,540 Does that function call execute? 1079 00:52:35,540 --> 00:52:36,350 Yes. 1080 00:52:36,350 --> 00:52:37,410 So the answer is yes. 1081 00:52:37,410 --> 00:52:41,010 This function call will execute. 1082 00:52:41,010 --> 00:52:42,418 But again, is it what we want? 1083 00:52:42,418 --> 00:52:49,250 1084 00:52:49,250 --> 00:52:52,204 >> What is one way we could figure out if it's what we want? 1085 00:52:52,204 --> 00:52:53,470 >> MULTIPLE STUDENTS: Run it? 1086 00:52:53,470 --> 00:52:54,460 >> JASON HIRSCHHORN: We could run it. 1087 00:52:54,460 --> 00:52:57,500 But before we do that, we could also reason through this. 1088 00:52:57,500 --> 00:52:57,920 If-- 1089 00:52:57,920 --> 00:53:01,920 say we have one byte in our file, we'll get to here, 1090 00:53:01,920 --> 00:53:02,660 we'll get to this code. 1091 00:53:02,660 --> 00:53:03,620 This will run. 1092 00:53:03,620 --> 00:53:07,780 fread will return one byte and store it in the buffer. 1093 00:53:07,780 --> 00:53:11,290 And this will evaluate to 1, right, after he returns 1. 1094 00:53:11,290 --> 00:53:12,640 >> So WHILE 1. 1095 00:53:12,640 --> 00:53:15,325 Does that mean the code inside the WHILE loop will execute? 1096 00:53:15,325 --> 00:53:15,453 >> STUDENT 47: Yeah. 1097 00:53:15,453 --> 00:53:16,040 It's true. 1098 00:53:16,040 --> 00:53:16,290 >> JASON HIRSCHHORN: Yes. 1099 00:53:16,290 --> 00:53:17,490 1 is true. 1100 00:53:17,490 --> 00:53:18,240 It's not 0. 1101 00:53:18,240 --> 00:53:20,360 So the code inside here will execute. 1102 00:53:20,360 --> 00:53:22,300 So we'll write that. 1103 00:53:22,300 --> 00:53:25,340 We'll move back to this line once again. 1104 00:53:25,340 --> 00:53:26,850 Now we have-- 1105 00:53:26,850 --> 00:53:28,550 we're at the end of our file. 1106 00:53:28,550 --> 00:53:30,980 We read from the end of our file, because we only had one byte in it. 1107 00:53:30,980 --> 00:53:34,270 >> Fread returns 0, stores something in buffer. 1108 00:53:34,270 --> 00:53:35,890 I honestly don't know what it stores in buffer. 1109 00:53:35,890 --> 00:53:38,380 We could probably look up to see what it does. 1110 00:53:38,380 --> 00:53:40,130 That I honestly don't know. 1111 00:53:40,130 --> 00:53:43,090 We don't know, who cares what it stores in buffer? 1112 00:53:43,090 --> 00:53:44,010 But it does return 0. 1113 00:53:44,010 --> 00:53:45,440 And will WHILE 0 execute? 1114 00:53:45,440 --> 00:53:49,950 1115 00:53:49,950 --> 00:53:51,180 >> WHILE 0 won't execute. 1116 00:53:51,180 --> 00:53:54,030 So then we'll move down here. 1117 00:53:54,030 --> 00:53:58,870 So let's get a show of hands if this is the code we should run, or if we 1118 00:53:58,870 --> 00:54:00,140 should do changes first. 1119 00:54:00,140 --> 00:54:02,180 So if you think-- you have to vote. 1120 00:54:02,180 --> 00:54:06,885 If you think we should run this code as is, please raise your hand. 1121 00:54:06,885 --> 00:54:12,440 1122 00:54:12,440 --> 00:54:13,400 >> OK. 1123 00:54:13,400 --> 00:54:14,315 There's one-- 1124 00:54:14,315 --> 00:54:17,260 do you have a question, concern? 1125 00:54:17,260 --> 00:54:18,080 Yeah. 1126 00:54:18,080 --> 00:54:21,240 >> STUDENT 48: After we move buffer outside of the loop, do we 1127 00:54:21,240 --> 00:54:22,670 have to malloc it? 1128 00:54:22,670 --> 00:54:23,310 >> JASON HIRSCHHORN: Great question. 1129 00:54:23,310 --> 00:54:26,670 After we move buffer outside of the loop, do we have to malloc it? 1130 00:54:26,670 --> 00:54:28,400 This is a scope question. 1131 00:54:28,400 --> 00:54:32,130 If we initialize buffer outside of this loop, will it exist 1132 00:54:32,130 --> 00:54:33,534 inside of the loop? 1133 00:54:33,534 --> 00:54:35,230 >> MULTIPLE STUDENTS: Yes. 1134 00:54:35,230 --> 00:54:35,580 >> JASON HIRSCHHORN: Yes. 1135 00:54:35,580 --> 00:54:40,100 Its scope covers inside of the loop, and, really, anything below it inside 1136 00:54:40,100 --> 00:54:42,460 of this code, including the things inside here. 1137 00:54:42,460 --> 00:54:43,930 So we don't need to malloc it. 1138 00:54:43,930 --> 00:54:47,766 It's a local variable, and its scope still includes the loop. 1139 00:54:47,766 --> 00:54:49,540 >> STUDENT 49: Do we need to free it? 1140 00:54:49,540 --> 00:54:51,770 >> JASON HIRSCHHORN: Do we need to free buffer? 1141 00:54:51,770 --> 00:54:53,860 >> STUDENT 49: Yeah, if we don't malloc. 1142 00:54:53,860 --> 00:54:55,750 >> JASON HIRSCHHORN: Do we need to free buffer? 1143 00:54:55,750 --> 00:54:57,160 We don't. 1144 00:54:57,160 --> 00:55:01,280 Again, it is a local variable, so we don't need to free it. 1145 00:55:01,280 --> 00:55:02,170 OK. 1146 00:55:02,170 --> 00:55:03,480 Let's see what happens. 1147 00:55:03,480 --> 00:55:17,290 1148 00:55:17,290 --> 00:55:18,220 So it is uninitialized. 1149 00:55:18,220 --> 00:55:20,830 That was what something that Marcus proposed earlier. 1150 00:55:20,830 --> 00:55:25,340 So we have that error, variable buffer is uninitialized when used here. 1151 00:55:25,340 --> 00:55:26,590 >> How can we fix this? 1152 00:55:26,590 --> 00:55:29,460 1153 00:55:29,460 --> 00:55:30,960 >> STUDENT 50: Malloc it? 1154 00:55:30,960 --> 00:55:31,770 >> STUDENT 51: Equals NULL? 1155 00:55:31,770 --> 00:55:33,000 >> STUDENT 52: Say buffer equals NULL. 1156 00:55:33,000 --> 00:55:34,250 >> JASON HIRSCHHORN: OK. 1157 00:55:34,250 --> 00:55:40,040 1158 00:55:40,040 --> 00:55:40,770 Looks good. 1159 00:55:40,770 --> 00:55:42,410 We have it now. 1160 00:55:42,410 --> 00:55:45,630 Let's create something to try copying. 1161 00:55:45,630 --> 00:56:08,990 1162 00:56:08,990 --> 00:56:10,490 So we have our text file. 1163 00:56:10,490 --> 00:56:11,740 How can we run this program? 1164 00:56:11,740 --> 00:56:14,140 1165 00:56:14,140 --> 00:56:15,472 Yeah. 1166 00:56:15,472 --> 00:56:22,230 >> STUDENT 53: You can do dot slash cp, test.txt. 1167 00:56:22,230 --> 00:56:25,140 And then you can name another file which it will store into. 1168 00:56:25,140 --> 00:56:25,510 >> JASON HIRSCHHORN: OK. 1169 00:56:25,510 --> 00:56:27,380 We'll call it out.txt. 1170 00:56:27,380 --> 00:56:28,630 Cool? 1171 00:56:28,630 --> 00:56:31,700 1172 00:56:31,700 --> 00:56:34,320 Seg fault. 1173 00:56:34,320 --> 00:56:35,570 Thoughts on the seg fault? 1174 00:56:35,570 --> 00:56:40,900 1175 00:56:40,900 --> 00:56:41,390 This is great. 1176 00:56:41,390 --> 00:56:45,040 How can we find out where the seg fault is? 1177 00:56:45,040 --> 00:56:45,680 What? 1178 00:56:45,680 --> 00:56:45,990 >> STUDENT 54: Gdb. 1179 00:56:45,990 --> 00:56:47,240 >> JASON HIRSCHHORN: Gdb. 1180 00:56:47,240 --> 00:56:51,400 1181 00:56:51,400 --> 00:56:55,300 We run gdb by writing gdb dot slash, the name of our program. 1182 00:56:55,300 --> 00:56:57,020 No command line arguments there. 1183 00:56:57,020 --> 00:56:59,570 We're going to set a breakpoint at main. 1184 00:56:59,570 --> 00:57:02,190 If I want to start gdb, what do I do? 1185 00:57:02,190 --> 00:57:02,730 >> STUDENT 55: R. 1186 00:57:02,730 --> 00:57:08,910 >> JASON HIRSCHHORN: R. And then what? 1187 00:57:08,910 --> 00:57:09,400 >> STUDENT 55: The arguments? 1188 00:57:09,400 --> 00:57:10,650 >> JASON HIRSCHHORN: Then the command-line arguments. 1189 00:57:10,650 --> 00:57:15,890 1190 00:57:15,890 --> 00:57:17,120 Let's walk through. 1191 00:57:17,120 --> 00:57:19,090 N is just taking me line by line. 1192 00:57:19,090 --> 00:57:21,450 I'm going to go until I get my seg fault. 1193 00:57:21,450 --> 00:57:22,700 There's my seg fault. 1194 00:57:22,700 --> 00:57:24,960 1195 00:57:24,960 --> 00:57:27,875 It looks like fread caused my seg fault. 1196 00:57:27,875 --> 00:57:30,570 1197 00:57:30,570 --> 00:57:32,770 I know fread caused my seg fault, because that was the 1198 00:57:32,770 --> 00:57:34,950 line we just executed. 1199 00:57:34,950 --> 00:57:36,530 >> And the only thing that was happening in that line-- 1200 00:57:36,530 --> 00:57:37,520 two things were happening. 1201 00:57:37,520 --> 00:57:40,610 Fread was going, and then we were doing some WHILE checking. 1202 00:57:40,610 --> 00:57:44,820 I'm willing to bet that the WHILE checking was not causing my seg fault. 1203 00:57:44,820 --> 00:57:46,950 Most likely, fread was causing my seg fault. 1204 00:57:46,950 --> 00:57:49,260 I also see something here, memcopy. 1205 00:57:49,260 --> 00:57:50,500 >> Memory copy. 1206 00:57:50,500 --> 00:57:53,820 Sounds like moving memory from one location to the other. 1207 00:57:53,820 --> 00:57:56,890 Sounds like something that would happen in fread, maybe some memory 1208 00:57:56,890 --> 00:57:58,910 moving from here to here. 1209 00:57:58,910 --> 00:58:01,740 1210 00:58:01,740 --> 00:58:03,860 Let's go through this again. 1211 00:58:03,860 --> 00:58:06,900 How do I start it over and run it again? 1212 00:58:06,900 --> 00:58:08,092 Yeah. 1213 00:58:08,092 --> 00:58:15,140 >> STUDENT 56: Do you need to put an ampersand before buffer? 1214 00:58:15,140 --> 00:58:17,800 >> JASON HIRSCHHORN: So ampersand before buffer would give me the address of 1215 00:58:17,800 --> 00:58:22,330 buffer, which is a char*. 1216 00:58:22,330 --> 00:58:25,250 Let's run through this one more time. 1217 00:58:25,250 --> 00:58:28,248 How do I run through it one more time? 1218 00:58:28,248 --> 00:58:29,210 >> STUDENT 57: Can you just type run again? 1219 00:58:29,210 --> 00:58:32,050 >> JASON HIRSCHHORN: Just type run again. 1220 00:58:32,050 --> 00:58:33,415 So we're not going to execute this line. 1221 00:58:33,415 --> 00:58:36,250 1222 00:58:36,250 --> 00:58:39,240 So buffer is a NULL pointer. 1223 00:58:39,240 --> 00:58:40,490 Correct? 1224 00:58:40,490 --> 00:58:45,870 1225 00:58:45,870 --> 00:58:47,060 It is pointing to-- let's see. 1226 00:58:47,060 --> 00:58:48,500 If we have our-- 1227 00:58:48,500 --> 00:58:50,430 draw a quick picture of this. 1228 00:58:50,430 --> 00:58:53,500 Can everybody see if I write over here? 1229 00:58:53,500 --> 00:59:02,890 >> So in the stack, we have a local variable and it's called buffer, and 1230 00:59:02,890 --> 00:59:08,230 it's a pointer to a char. 1231 00:59:08,230 --> 00:59:10,325 What address is this char at? 1232 00:59:10,325 --> 00:59:12,550 >> STUDENT 58: 0x0. 1233 00:59:12,550 --> 00:59:13,400 >> JASON HIRSCHHORN: Right. 1234 00:59:13,400 --> 00:59:14,200 That's what this is. 1235 00:59:14,200 --> 00:59:17,600 In here, inside buffer, is stored 0x0. 1236 00:59:17,600 --> 00:59:20,480 That's what we have-- the setup we have right now. 1237 00:59:20,480 --> 00:59:27,540 So this line, fread, puts something from source where? 1238 00:59:27,540 --> 00:59:30,560 Into this box or this box? 1239 00:59:30,560 --> 00:59:31,060 Which box? 1240 00:59:31,060 --> 00:59:33,290 Left box or right box? 1241 00:59:33,290 --> 00:59:34,750 This right box. 1242 00:59:34,750 --> 00:59:38,440 >> It follows the pointer, and puts it in here. 1243 00:59:38,440 --> 00:59:42,620 When we try and touch memory at location 0, what do we get? 1244 00:59:42,620 --> 00:59:45,050 A segmentation fault. 1245 00:59:45,050 --> 00:59:46,550 That's the error we have right now. 1246 00:59:46,550 --> 00:59:46,970 Yeah. 1247 00:59:46,970 --> 00:59:48,410 >> STUDENT 59: Don't you have to put star buffer? 1248 00:59:48,410 --> 00:59:49,180 Or no? 1249 00:59:49,180 --> 00:59:50,050 For fread? 1250 00:59:50,050 --> 00:59:51,450 >> JASON HIRSCHHORN: So fread takes a pointer. 1251 00:59:51,450 --> 00:59:54,920 1252 00:59:54,920 --> 00:59:55,900 So it passes in buffer. 1253 00:59:55,900 --> 00:59:58,980 And then it'll de-reference it somewhere inside fread. 1254 00:59:58,980 --> 01:00:00,700 But again, we saw, it takes a pointer. 1255 01:00:00,700 --> 01:00:02,560 We don't need to pass it star buffer. 1256 01:00:02,560 --> 01:00:05,350 That would be passing it whatever's here. 1257 01:00:05,350 --> 01:00:07,980 And that would probably give us an error because we're de-referencing it. 1258 01:00:07,980 --> 01:00:08,150 >> Right? 1259 01:00:08,150 --> 01:00:10,690 When we de-reference this pointer, when we try to access this location, 1260 01:00:10,690 --> 01:00:13,140 we're getting an error-- our segmentation fault. 1261 01:00:13,140 --> 01:00:15,800 So-- 1262 01:00:15,800 --> 01:00:16,690 oops. 1263 01:00:16,690 --> 01:00:19,090 We're going to quit out of gdb. 1264 01:00:19,090 --> 01:00:20,160 Our line-- 1265 01:00:20,160 --> 01:00:22,990 our problem-- is right here on this line. 1266 01:00:22,990 --> 01:00:26,410 And it's a problem because of this line. 1267 01:00:26,410 --> 01:00:31,780 >> How can we create a box that is accessible in fread. 1268 01:00:31,780 --> 01:00:31,980 Right? 1269 01:00:31,980 --> 01:00:35,190 We need to create a box that's one byte large, the size of a char. 1270 01:00:35,190 --> 01:00:38,590 But we need that box to be accessible when this function executes. 1271 01:00:38,590 --> 01:00:39,390 So where-- 1272 01:00:39,390 --> 01:00:39,640 yeah. 1273 01:00:39,640 --> 01:00:40,440 Any ideas? 1274 01:00:40,440 --> 01:00:43,615 >> STUDENT 60: Just set it as any random character. 1275 01:00:43,615 --> 01:00:49,150 1276 01:00:49,150 --> 01:00:51,640 Just do char buffer equals the character. 1277 01:00:51,640 --> 01:00:53,795 And then, when you have buffer there-- 1278 01:00:53,795 --> 01:00:54,110 >> JASON HIRSCHHORN: Wait. 1279 01:00:54,110 --> 01:00:55,110 Char buffer? 1280 01:00:55,110 --> 01:00:55,880 So no star? 1281 01:00:55,880 --> 01:00:56,390 >> STUDENT 60: Yeah. 1282 01:00:56,390 --> 01:00:58,560 Take out the star. 1283 01:00:58,560 --> 01:01:00,690 Equals a random character. 1284 01:01:00,690 --> 01:01:01,460 >> JASON HIRSCHHORN: OK. 1285 01:01:01,460 --> 01:01:02,420 So give me one. 1286 01:01:02,420 --> 01:01:03,170 >> STUDENT 60: Like a or something. 1287 01:01:03,170 --> 01:01:06,160 And then when you have buffer there, you use a-- 1288 01:01:06,160 --> 01:01:06,420 >> STUDENT 61: Star? 1289 01:01:06,420 --> 01:01:07,650 Oh no, the ampersand. 1290 01:01:07,650 --> 01:01:09,000 >> STUDENT 60: Use the ampersand. 1291 01:01:09,000 --> 01:01:09,470 >> JASON HIRSCHHORN: OK. 1292 01:01:09,470 --> 01:01:11,320 And what about in fwrite? 1293 01:01:11,320 --> 01:01:14,150 >> STUDENT 60: Use the ampersand again. 1294 01:01:14,150 --> 01:01:14,320 >> JASON HIRSCHHORN: All right. 1295 01:01:14,320 --> 01:01:20,970 So your idea is, we create a char and put something in it, and then 1296 01:01:20,970 --> 01:01:22,612 write to that char. 1297 01:01:22,612 --> 01:01:23,760 >> STUDENT 60: Yeah. 1298 01:01:23,760 --> 01:01:25,916 >> JASON HIRSCHHORN: What do people think? 1299 01:01:25,916 --> 01:01:27,770 >> STUDENT 62: It's convoluted. 1300 01:01:27,770 --> 01:01:28,460 >> JASON HIRSCHHORN: OK. 1301 01:01:28,460 --> 01:01:29,760 Let's draw it out. 1302 01:01:29,760 --> 01:01:35,720 So this time, I'm going to draw this in red on the stack here, and then we 1303 01:01:35,720 --> 01:01:36,410 will have-- 1304 01:01:36,410 --> 01:01:36,822 ooh! 1305 01:01:36,822 --> 01:01:38,060 Sorry. 1306 01:01:38,060 --> 01:01:45,930 So this time we have something called buffer, and it's on the stack. 1307 01:01:45,930 --> 01:01:48,430 Correct? 1308 01:01:48,430 --> 01:01:51,520 And we're saving in it a, initially. 1309 01:01:51,520 --> 01:01:53,830 >> Then we have our call to fread. 1310 01:01:53,830 --> 01:02:01,300 What fread does is it takes a byte from our file and puts it somewhere. 1311 01:02:01,300 --> 01:02:04,570 It puts it in whatever the thing's pointing to. 1312 01:02:04,570 --> 01:02:09,130 Well, before we had this address-- 1313 01:02:09,130 --> 01:02:10,250 0x0. 1314 01:02:10,250 --> 01:02:13,349 Now what address do we have? 1315 01:02:13,349 --> 01:02:14,650 >> STUDENT 63: Whatever address buffer is. 1316 01:02:14,650 --> 01:02:15,970 >> JASON HIRSCHHORN: Whatever address buffer is. 1317 01:02:15,970 --> 01:02:22,370 It's probably going to be something like that. 1318 01:02:22,370 --> 01:02:26,950 Probably going to start with a b and an f, and then have six other 1319 01:02:26,950 --> 01:02:27,970 hexadecimal digits. 1320 01:02:27,970 --> 01:02:28,480 Doesn't matter. 1321 01:02:28,480 --> 01:02:29,470 Some address. 1322 01:02:29,470 --> 01:02:31,410 And we're passing that address in. 1323 01:02:31,410 --> 01:02:34,790 >> And we're going to put our one byte thing at that address. 1324 01:02:34,790 --> 01:02:38,470 So we're going to put our one byte thing inside here. 1325 01:02:38,470 --> 01:02:40,800 And then we're going to write from what's ever inside here. 1326 01:02:40,800 --> 01:02:43,425 1327 01:02:43,425 --> 01:02:45,380 Does anybody have any questions about that? 1328 01:02:45,380 --> 01:02:50,990 1329 01:02:50,990 --> 01:02:54,690 Who thinks this code will work? 1330 01:02:54,690 --> 01:02:56,020 >> Raise your hand if you think this code will work. 1331 01:02:56,020 --> 01:02:57,270 You have to take a stance. 1332 01:02:57,270 --> 01:03:00,670 1333 01:03:00,670 --> 01:03:02,500 And who thinks this code won't work? 1334 01:03:02,500 --> 01:03:04,610 Raise your hand. 1335 01:03:04,610 --> 01:03:06,750 Everybody else should be raising their hand. 1336 01:03:06,750 --> 01:03:07,670 OK. 1337 01:03:07,670 --> 01:03:09,390 Michael, where are you standing? 1338 01:03:09,390 --> 01:03:10,680 >> MICHAEL: I can't decide. 1339 01:03:10,680 --> 01:03:12,070 Kind of in the middle. 1340 01:03:12,070 --> 01:03:12,736 >> JASON HIRSCHHORN: You're in the middle. 1341 01:03:12,736 --> 01:03:13,092 Pick one. 1342 01:03:13,092 --> 01:03:14,400 >> MICHAEL: I'll have faith and say it will work. 1343 01:03:14,400 --> 01:03:14,660 >> JASON HIRSCHHORN: OK. 1344 01:03:14,660 --> 01:03:16,047 You'll have faith and say it works? 1345 01:03:16,047 --> 01:03:26,490 1346 01:03:26,490 --> 01:03:27,020 What happened? 1347 01:03:27,020 --> 01:03:28,270 >> [INTERPOSING VOICES] 1348 01:03:28,270 --> 01:03:35,170 1349 01:03:35,170 --> 01:03:35,950 >> JASON HIRSCHHORN: No seg fault. 1350 01:03:35,950 --> 01:03:40,320 How can we check to see if two things are equal? 1351 01:03:40,320 --> 01:03:42,060 Two files are equal. 1352 01:03:42,060 --> 01:03:43,300 >> STUDENT 64: Diff. 1353 01:03:43,300 --> 01:03:45,490 >> JASON HIRSCHHORN: Diff. 1354 01:03:45,490 --> 01:03:51,630 Diff checks for the differences between two files, and if it returns 1355 01:03:51,630 --> 01:03:52,890 nothing, they're identical. 1356 01:03:52,890 --> 01:03:59,030 And if we open up, we get our file. 1357 01:03:59,030 --> 01:04:00,490 So that was the correct solution. 1358 01:04:00,490 --> 01:04:01,780 Let's look back at it one more time. 1359 01:04:01,780 --> 01:04:04,080 We actually didn't even need to initialize it. 1360 01:04:04,080 --> 01:04:05,520 >> It would probably look a bit cleaner if you didn't put 1361 01:04:05,520 --> 01:04:07,680 something random in there. 1362 01:04:07,680 --> 01:04:13,070 The point being, you needed to create some space to store something from 1363 01:04:13,070 --> 01:04:15,530 fread and take something out of fwrite. 1364 01:04:15,530 --> 01:04:18,400 And that thing had to be either a local variable on the stack-- you 1365 01:04:18,400 --> 01:04:19,890 could've malloc'd some space. 1366 01:04:19,890 --> 01:04:23,030 >> So we actually could have written malloc here, and 1367 01:04:23,030 --> 01:04:25,420 that would have worked. 1368 01:04:25,420 --> 01:04:28,660 And then we would have been storing our things somewhere on the heap. 1369 01:04:28,660 --> 01:04:31,940 But this is actually, probably, the most elegant solution. 1370 01:04:31,940 --> 01:04:34,490 Just create some space on the stack for these things to go. 1371 01:04:34,490 --> 01:04:37,690 1372 01:04:37,690 --> 01:04:38,990 >> I would have two other comments. 1373 01:04:38,990 --> 01:04:44,650 If you were to take turn in this, and then get scored on this, my comments 1374 01:04:44,650 --> 01:04:47,400 would be as follows. 1375 01:04:47,400 --> 01:04:54,300 These 1's here, to me, look like magic numbers. 1376 01:04:54,300 --> 01:04:56,860 This 1, in terms of fread, makes sense. 1377 01:04:56,860 --> 01:04:59,580 That's the number of things to read or write. 1378 01:04:59,580 --> 01:05:03,740 >> But this one right here should probably be something else. 1379 01:05:03,740 --> 01:05:05,180 So what is one solution? 1380 01:05:05,180 --> 01:05:06,545 >> STUDENT 65: Size of byte. 1381 01:05:06,545 --> 01:05:10,100 1382 01:05:10,100 --> 01:05:11,080 >> JASON HIRSCHHORN: Like that? 1383 01:05:11,080 --> 01:05:13,130 >> STUDENT 65: Size of char. 1384 01:05:13,130 --> 01:05:13,820 >> JASON HIRSCHHORN: Size of char. 1385 01:05:13,820 --> 01:05:15,290 Yeah, byte is not a type. 1386 01:05:15,290 --> 01:05:16,320 So size of char works. 1387 01:05:16,320 --> 01:05:30,270 We could have, at the top of our code, #defined that. 1388 01:05:30,270 --> 01:05:33,410 Called something BYTE and it's really a char. 1389 01:05:33,410 --> 01:05:37,675 Actually, an even better approach might have been this-- 1390 01:05:37,675 --> 01:05:39,391 uint. 1391 01:05:39,391 --> 01:05:40,780 Anybody know what that is? 1392 01:05:40,780 --> 01:05:44,388 1393 01:05:44,388 --> 01:05:44,840 >> Sorry. 1394 01:05:44,840 --> 01:05:46,090 I have it backwards. 1395 01:05:46,090 --> 01:05:51,620 1396 01:05:51,620 --> 01:05:52,200 Wait, no. 1397 01:05:52,200 --> 01:05:53,450 Which way does it go? 1398 01:05:53,450 --> 01:05:58,071 1399 01:05:58,071 --> 01:05:59,660 Anybody know what that is? 1400 01:05:59,660 --> 01:06:00,950 Yeah. 1401 01:06:00,950 --> 01:06:05,650 >> STUDENT 67: Supposed to help standardize across systems things that 1402 01:06:05,650 --> 01:06:08,760 have-- like unsigned integers that have 8 bytes? 1403 01:06:08,760 --> 01:06:11,785 >> JASON HIRSCHHORN: That's exactly right. 1404 01:06:11,785 --> 01:06:14,310 On different machines, the size of a char-- 1405 01:06:14,310 --> 01:06:15,180 not usually a char. 1406 01:06:15,180 --> 01:06:16,100 Chars are usually one byte. 1407 01:06:16,100 --> 01:06:19,590 But the size of other data types are different sizes on a 32-bit machine 1408 01:06:19,590 --> 01:06:21,370 versus a 64-bit machine. 1409 01:06:21,370 --> 01:06:25,180 A uint8_t is always 8 bits-- 1410 01:06:25,180 --> 01:06:27,210 always one byte. 1411 01:06:27,210 --> 01:06:29,580 >> And I need to include that standard int header file. 1412 01:06:29,580 --> 01:06:35,040 So now, this would have probably been the best way to write this code. 1413 01:06:35,040 --> 01:06:40,160 1414 01:06:40,160 --> 01:06:41,450 So I get rid of the magic numbers. 1415 01:06:41,450 --> 01:06:44,690 And I also have a more logical type for buffer. 1416 01:06:44,690 --> 01:06:49,450 It is not simply a char, it is a byte, which is what we expect it to be. 1417 01:06:49,450 --> 01:06:53,400 >> And up here, we've actually been a bit more robust. 1418 01:06:53,400 --> 01:06:55,190 We're not calling it a char, which-- 1419 01:06:55,190 --> 01:06:58,630 maybe, who knows-- could be a different size on different machines. 1420 01:06:58,630 --> 01:07:02,025 We're actually saying this is exactly one byte, always, no matter what. 1421 01:07:02,025 --> 01:07:05,810 And if we look here, we make cp. 1422 01:07:05,810 --> 01:07:08,340 Uh-oh. 1423 01:07:08,340 --> 01:07:09,590 What happened? 1424 01:07:09,590 --> 01:07:14,470 1425 01:07:14,470 --> 01:07:16,170 >> STUDENT 68: It might be switched. 1426 01:07:16,170 --> 01:07:17,880 >> JASON HIRSCHHORN: What? 1427 01:07:17,880 --> 01:07:19,130 >> STUDENT 69: Is it? 1428 01:07:19,130 --> 01:07:21,940 1429 01:07:21,940 --> 01:07:25,080 >> STUDENT 70: You didn't define it as a type. 1430 01:07:25,080 --> 01:07:28,684 >> STUDENT 71: But it should be defined in standard. 1431 01:07:28,684 --> 01:07:29,934 >> STUDENT 72: What's going on? 1432 01:07:29,934 --> 01:07:37,660 1433 01:07:37,660 --> 01:07:40,210 >> STUDENT 73: Should define be all caps? 1434 01:07:40,210 --> 01:07:41,370 >> JASON HIRSCHHORN: So it's not #define. 1435 01:07:41,370 --> 01:07:45,490 Actually, in this case, I'm going to use typedef. 1436 01:07:45,490 --> 01:07:48,590 Because we're using it as a type in one location. 1437 01:07:48,590 --> 01:07:51,990 So in this case, we actually want to typedef like we're printing a new type 1438 01:07:51,990 --> 01:07:54,490 byte, and it is, essentially, this. 1439 01:07:54,490 --> 01:07:56,590 It's a bit different than #define. 1440 01:07:56,590 --> 01:08:02,740 >> And now, our code works perfectly. 1441 01:08:02,740 --> 01:08:05,230 So, again, #define takes something, replaces it everywhere 1442 01:08:05,230 --> 01:08:06,780 with the other thing. 1443 01:08:06,780 --> 01:08:07,920 It's just a macro-- 1444 01:08:07,920 --> 01:08:09,420 shorthand to get rid of magic numbers. 1445 01:08:09,420 --> 01:08:11,360 But in this case, because we're using it as a type-- 1446 01:08:11,360 --> 01:08:12,180 right here-- 1447 01:08:12,180 --> 01:08:19,880 in order for that to work, we need to typedef whatever byte is. 1448 01:08:19,880 --> 01:08:21,840 >> And we're defining it right here. 1449 01:08:21,840 --> 01:08:24,750 It's not a struct, it's actually just an unsigned integer. 1450 01:08:24,750 --> 01:08:27,680 It's one byte long. 1451 01:08:27,680 --> 01:08:31,910 This code will be available online, and you all should have it right now. 1452 01:08:31,910 --> 01:08:33,830 >> So we have-- 1453 01:08:33,830 --> 01:08:34,250 perfect-- 1454 01:08:34,250 --> 01:08:41,359 13 minutes left to go over problem set 5. 1455 01:08:41,359 --> 01:08:44,270 I want to walk through copy.c together, and then we'll talk briefly 1456 01:08:44,270 --> 01:08:47,120 about the other parts of the problem set. 1457 01:08:47,120 --> 01:08:48,899 So let me pull up copy.c. 1458 01:08:48,899 --> 01:09:03,930 1459 01:09:03,930 --> 01:09:08,810 And the cool thing is, we've actually already written a lot of this code. 1460 01:09:08,810 --> 01:09:11,180 >> The code we wrote literally just came out of here when I was 1461 01:09:11,180 --> 01:09:13,120 writing this on my own. 1462 01:09:13,120 --> 01:09:16,990 But this is copy.c, forms the foundation for the first two parts of 1463 01:09:16,990 --> 01:09:22,340 the problem set for whodunit.c, which you need to write, and resize.c. 1464 01:09:22,340 --> 01:09:27,050 Recover.c, which is the third and final part of the problem set, is not 1465 01:09:27,050 --> 01:09:29,529 based off of this file. 1466 01:09:29,529 --> 01:09:32,200 >> You're going to need to write that file, we give you a template for that 1467 01:09:32,200 --> 01:09:34,620 file, but it has nothing to do with copy.c. 1468 01:09:34,620 --> 01:09:38,675 But because copy.c is the foundation for the first two parts, we're going 1469 01:09:38,675 --> 01:09:42,000 to walk through it now, so you have a good sense of what it does. 1470 01:09:42,000 --> 01:09:43,640 >> And the comments give some of it away. 1471 01:09:43,640 --> 01:09:45,120 We've already written some of this. 1472 01:09:45,120 --> 01:09:49,220 First, we're making sure we get three arguments. 1473 01:09:49,220 --> 01:09:50,560 Next, we're remembering the file name. 1474 01:09:50,560 --> 01:09:52,960 So we skipped this step when we coded our thing-- 1475 01:09:52,960 --> 01:09:54,700 when our cp. 1476 01:09:54,700 --> 01:09:56,750 But here, they're making it a bit cleaner. 1477 01:09:56,750 --> 01:09:59,350 >> They're checking to make sure both files are good, in 1478 01:09:59,350 --> 01:10:00,450 addition to opening them. 1479 01:10:00,450 --> 01:10:04,760 We wrote all this code just now, so I'm not going to dwell on this code. 1480 01:10:04,760 --> 01:10:09,670 Next is some stuff that's specific to the types of files we're using, which 1481 01:10:09,670 --> 01:10:12,240 are bitmap files. 1482 01:10:12,240 --> 01:10:15,660 Bitmap files have some metadata associated with them. 1483 01:10:15,660 --> 01:10:20,190 >> So the first couple of bytes tell you about the file. 1484 01:10:20,190 --> 01:10:23,460 They aren't the colors of the pixel in that image. 1485 01:10:23,460 --> 01:10:25,120 They tell you about the file. 1486 01:10:25,120 --> 01:10:28,220 And if you read through the problem set, you'll have much more information 1487 01:10:28,220 --> 01:10:33,100 on what types of metadata structures are included with bitmaps. 1488 01:10:33,100 --> 01:10:39,350 >> But that's why we have this first set of-- this code right here. 1489 01:10:39,350 --> 01:10:42,490 We are reading the metadata-- 1490 01:10:42,490 --> 01:10:45,800 two pieces of metadata-- the file header and the info header. 1491 01:10:45,800 --> 01:10:51,030 And we are checking some parts of it to make sure it is a true bitmap file 1492 01:10:51,030 --> 01:10:52,420 before continuing. 1493 01:10:52,420 --> 01:10:55,470 >> And again, these are details we don't need to go into now. 1494 01:10:55,470 --> 01:10:57,720 If you read through the problem set, you will understand these. 1495 01:10:57,720 --> 01:11:01,370 Long story short, these are just saying, this is a bitmap file, and 1496 01:11:01,370 --> 01:11:02,810 confirming that. 1497 01:11:02,810 --> 01:11:05,180 >> Next, we're writing those to the out file. 1498 01:11:05,180 --> 01:11:05,660 We see that here. 1499 01:11:05,660 --> 01:11:06,910 We're writing to the out pointer. 1500 01:11:06,910 --> 01:11:09,260 1501 01:11:09,260 --> 01:11:11,320 Next, we're determining padding. 1502 01:11:11,320 --> 01:11:15,240 So again, as is particularity with a bitmap file, some lines include 1503 01:11:15,240 --> 01:11:16,840 padding at the end. 1504 01:11:16,840 --> 01:11:19,000 And if you read through the problem set, you'll learn more about padding. 1505 01:11:19,000 --> 01:11:22,330 This is the formula to find padding. 1506 01:11:22,330 --> 01:11:23,610 >> Important to remember-- 1507 01:11:23,610 --> 01:11:29,720 when you change the size of a bitmap file, the padding changes. 1508 01:11:29,720 --> 01:11:31,970 When you change the size of a file, the padding changes. 1509 01:11:31,970 --> 01:11:34,310 It's never going to be greater than 3-- 1510 01:11:34,310 --> 01:11:36,510 it'll be 0 through 3, inclusive. 1511 01:11:36,510 --> 01:11:38,930 But when you change the size of something, the padding changes. 1512 01:11:38,930 --> 01:11:47,100 >> If I only have one pixel in that row, I need three bytes of padding, because 1513 01:11:47,100 --> 01:11:51,190 each row has to be multiples of four bytes long in a bitmap file. 1514 01:11:51,190 --> 01:11:56,120 But if I double it, to go from one pixel to two pixel, each of which, 1515 01:11:56,120 --> 01:11:59,510 let's say, is a byte, then I need two bytes of padding to make 1516 01:11:59,510 --> 01:12:00,970 that equal to four. 1517 01:12:00,970 --> 01:12:04,200 >> So when I change the size of something, I need to change the amount 1518 01:12:04,200 --> 01:12:06,551 of padding I have. 1519 01:12:06,551 --> 01:12:08,100 Does that make sense to everyone? 1520 01:12:08,100 --> 01:12:12,020 1521 01:12:12,020 --> 01:12:18,720 Next, we iterate over each row, or through all the rows. 1522 01:12:18,720 --> 01:12:21,400 And then we iterate through each column in each row. 1523 01:12:21,400 --> 01:12:25,330 We're treating this bitmap like a grid, like we've treated 1524 01:12:25,330 --> 01:12:26,490 the board in 15. 1525 01:12:26,490 --> 01:12:29,200 >> Like we treated the bricks when we printed them on the screen. 1526 01:12:29,200 --> 01:12:31,350 A grid of rows and columns. 1527 01:12:31,350 --> 01:12:32,350 Then-- we saw this. 1528 01:12:32,350 --> 01:12:33,840 We actually just coded this. 1529 01:12:33,840 --> 01:12:35,780 We created some temporary storage. 1530 01:12:35,780 --> 01:12:38,710 We read in there, and then we write it out. 1531 01:12:38,710 --> 01:12:42,680 This is exactly what we just did. 1532 01:12:42,680 --> 01:12:46,760 >> Next, because I said each line ends in some padding, we 1533 01:12:46,760 --> 01:12:48,260 skip over that padding-- 1534 01:12:48,260 --> 01:12:51,000 the old padding. 1535 01:12:51,000 --> 01:12:52,630 And then we add it back. 1536 01:12:52,630 --> 01:12:55,140 In this case, we're creating the same exact file. 1537 01:12:55,140 --> 01:12:56,180 We're just copying it. 1538 01:12:56,180 --> 01:12:57,700 So this line is kind of silly. 1539 01:12:57,700 --> 01:12:59,660 We could literally just put the padding in. 1540 01:12:59,660 --> 01:13:04,290 >> But if you change the size of the file, do you still want this line? 1541 01:13:04,290 --> 01:13:08,510 1542 01:13:08,510 --> 01:13:11,560 So if we change the size of a file, do we still want to skip 1543 01:13:11,560 --> 01:13:12,810 over the old padding? 1544 01:13:12,810 --> 01:13:15,170 1545 01:13:15,170 --> 01:13:15,970 >> STUDENT 74: Yes. 1546 01:13:15,970 --> 01:13:17,090 >> JASON HIRSCHHORN: So we do. 1547 01:13:17,090 --> 01:13:19,290 Because this, again, deals with the source file. 1548 01:13:19,290 --> 01:13:21,570 We don't care about the padding from the source file. 1549 01:13:21,570 --> 01:13:23,410 We want to go to the next line. 1550 01:13:23,410 --> 01:13:28,850 But we don't simply put back the old amount of padding. 1551 01:13:28,850 --> 01:13:31,540 We need to put back the new amount of padding. 1552 01:13:31,540 --> 01:13:35,810 >> So when we're changing the size of a file, we still want to skip over the 1553 01:13:35,810 --> 01:13:38,270 padding in the old file-- what we're reading in from. 1554 01:13:38,270 --> 01:13:40,370 But what we're writing to, we're going to need to put back some different 1555 01:13:40,370 --> 01:13:41,890 number of padding that we've determined. 1556 01:13:41,890 --> 01:13:42,780 Yeah. 1557 01:13:42,780 --> 01:13:44,550 >> STUDENT 75: The order of those two lines doesn't matter, right? 1558 01:13:44,550 --> 01:13:46,160 Because you're handling different files. 1559 01:13:46,160 --> 01:13:46,620 >> JASON HIRSCHHORN: Exactly. 1560 01:13:46,620 --> 01:13:48,220 The order of these two lines does not matter. 1561 01:13:48,220 --> 01:13:49,790 We write this line. 1562 01:13:49,790 --> 01:13:51,430 This is here for the file we're writing to. 1563 01:13:51,430 --> 01:13:54,370 That's important, so we get the right amount of padding. 1564 01:13:54,370 --> 01:13:57,560 This has to deal with the in file. 1565 01:13:57,560 --> 01:13:58,560 We want to skip right over the padding. 1566 01:13:58,560 --> 01:13:59,470 >> We don't want to read-- 1567 01:13:59,470 --> 01:14:01,500 if we're reading a byte at a time, we don't care about those padding bytes. 1568 01:14:01,500 --> 01:14:04,070 We want to move to the next line. 1569 01:14:04,070 --> 01:14:11,800 Finally just like Lucy gave for us, we close the files and return 0. 1570 01:14:11,800 --> 01:14:13,890 So this is copy.c. 1571 01:14:13,890 --> 01:14:17,850 And we actually wrote-- we spent most of section writing this, essentially. 1572 01:14:17,850 --> 01:14:18,740 >> You made this. 1573 01:14:18,740 --> 01:14:22,440 So hopefully you have a good sense of what's going on in here. 1574 01:14:22,440 --> 01:14:25,890 The big difference, honestly, is just this first part that deals with 1575 01:14:25,890 --> 01:14:29,970 peculiarities of bitmap files. 1576 01:14:29,970 --> 01:14:33,570 So I have as my next slide, what do we need to do? 1577 01:14:33,570 --> 01:14:35,510 Well, let's think about whodunit. 1578 01:14:35,510 --> 01:14:38,080 >> And for somebody who read through the problem set, what do we 1579 01:14:38,080 --> 01:14:41,410 need to do in whodunit? 1580 01:14:41,410 --> 01:14:42,080 Simply. 1581 01:14:42,080 --> 01:14:42,460 Aleja. 1582 01:14:42,460 --> 01:14:48,570 >> ALEJA: Can you take out the part of each pixel that denotes red. 1583 01:14:48,570 --> 01:14:49,730 And then-- 1584 01:14:49,730 --> 01:14:50,730 kind of? 1585 01:14:50,730 --> 01:14:51,860 >> JASON HIRSCHHORN: OK. 1586 01:14:51,860 --> 01:14:54,460 So take out the part of each pixel that denotes red. 1587 01:14:54,460 --> 01:14:57,234 That's close, but not all of it. 1588 01:14:57,234 --> 01:14:59,780 >> STUDENT 76: Well, there's different ways to do it. 1589 01:14:59,780 --> 01:14:59,870 >> JASON HIRSCHHORN: OK. 1590 01:14:59,870 --> 01:15:03,070 Give me one way. 1591 01:15:03,070 --> 01:15:08,240 >> STUDENT 76: Take out all the red, and then emphasize the blue and green. 1592 01:15:08,240 --> 01:15:10,010 >> JASON HIRSCHHORN: OK. 1593 01:15:10,010 --> 01:15:11,830 So given both these ways-- 1594 01:15:11,830 --> 01:15:15,210 it sounds like we give it a pixel, it has a red, blue, and green level. 1595 01:15:15,210 --> 01:15:19,350 We want to change the relative levels of the red, blue, and green, depending 1596 01:15:19,350 --> 01:15:20,740 on that pixel. 1597 01:15:20,740 --> 01:15:28,380 Where in this code should we change the relative red, blue, and green 1598 01:15:28,380 --> 01:15:29,720 levels of a given pixel. 1599 01:15:29,720 --> 01:15:30,600 After we've read it-- 1600 01:15:30,600 --> 01:15:32,520 before we write it? 1601 01:15:32,520 --> 01:15:34,564 Give me the line number. 1602 01:15:34,564 --> 01:15:35,950 >> MULTIPLE STUDENTS: 83. 1603 01:15:35,950 --> 01:15:37,320 >> JASON HIRSCHHORN: 83. 1604 01:15:37,320 --> 01:15:38,570 So right here. 1605 01:15:38,570 --> 01:15:40,830 1606 01:15:40,830 --> 01:15:45,710 For whodunit, the code you need to write should all go right there. 1607 01:15:45,710 --> 01:15:47,640 And that's the only code you need to write. 1608 01:15:47,640 --> 01:15:51,520 Because, like we heard, all you need to do is change these relative blue, 1609 01:15:51,520 --> 01:15:54,420 red, and green levels from each pixel. 1610 01:15:54,420 --> 01:15:58,250 >> You've read it in, and now you're going to write it out. 1611 01:15:58,250 --> 01:16:03,100 How do I get-- if I have this thing called triple, right here, and it's of 1612 01:16:03,100 --> 01:16:04,570 type RGBTRIPLE-- 1613 01:16:04,570 --> 01:16:08,650 well, if we looked in bmp.h, what is RGBTRIPLE? 1614 01:16:08,650 --> 01:16:11,450 1615 01:16:11,450 --> 01:16:12,700 >> STUDENT 77: It's a struct. 1616 01:16:12,700 --> 01:16:17,440 1617 01:16:17,440 --> 01:16:18,900 >> JASON HIRSCHHORN: RGBTRIPLE is a struct. 1618 01:16:18,900 --> 01:16:22,330 We see that right down here. 1619 01:16:22,330 --> 01:16:26,600 And so if I wanted to access, say, the red level of the struct, how do I 1620 01:16:26,600 --> 01:16:30,005 access the red level of this struct? 1621 01:16:30,005 --> 01:16:37,280 >> [CLASS MURMURS] 1622 01:16:37,280 --> 01:16:38,530 >> STUDENT 78: RGBTRIPLE.rgbtred? 1623 01:16:38,530 --> 01:16:47,250 1624 01:16:47,250 --> 01:16:48,856 >> JASON HIRSCHHORN: Is that correct? 1625 01:16:48,856 --> 01:16:53,040 >> STUDENT 79 : It should be triple dot, instead of RGBTRIPLE dot? 1626 01:16:53,040 --> 01:16:54,120 >> JASON HIRSCHHORN: Triple. 1627 01:16:54,120 --> 01:16:56,700 Triple is the local variable, so here, there's no pointers here. 1628 01:16:56,700 --> 01:16:58,400 So we just use the dot notation. 1629 01:16:58,400 --> 01:17:00,480 This will give me the level of red. 1630 01:17:00,480 --> 01:17:06,180 If I want to change it, I just set it equal to something different. 1631 01:17:06,180 --> 01:17:13,190 So again, this line of code accesses this variable inside this struct, and 1632 01:17:13,190 --> 01:17:15,070 we can set it to something new. 1633 01:17:15,070 --> 01:17:20,040 >> So for whodunit, again, this is, in essence, what we need to do. 1634 01:17:20,040 --> 01:17:21,170 Very simple. 1635 01:17:21,170 --> 01:17:25,020 Just change some relative levels, and this is where that code goes. 1636 01:17:25,020 --> 01:17:27,720 Resize, on the other hand, is a bit trickier. 1637 01:17:27,720 --> 01:17:30,900 In fact, resize is probably the trickiest part of this problem set. 1638 01:17:30,900 --> 01:17:32,720 We have three minutes to go over it. 1639 01:17:32,720 --> 01:17:34,910 >> But again, we've already written most of this code, so we 1640 01:17:34,910 --> 01:17:36,500 should be pretty familiar. 1641 01:17:36,500 --> 01:17:40,750 What are some things we want to do in resize, if you've read over the 1642 01:17:40,750 --> 01:17:43,470 problem set? 1643 01:17:43,470 --> 01:17:45,290 If you give them to me, we can talk about them. 1644 01:17:45,290 --> 01:17:47,340 What are some things we want to do? 1645 01:17:47,340 --> 01:17:47,970 >> STUDENT 80 : Vertically-- 1646 01:17:47,970 --> 01:17:52,360 so you have to horizontally resize it, but vertically resize it as well? 1647 01:17:52,360 --> 01:17:58,475 >> JASON HIRSCHHORN: So if we're given a pixel, and we want to resize it by a 1648 01:17:58,475 --> 01:18:03,460 factor of two, it now needs to be resized horizontally and resized 1649 01:18:03,460 --> 01:18:05,220 vertically. 1650 01:18:05,220 --> 01:18:06,640 Does that make sense? 1651 01:18:06,640 --> 01:18:07,060 Yeah. 1652 01:18:07,060 --> 01:18:09,300 So that's probably the biggest challenge. 1653 01:18:09,300 --> 01:18:10,430 And we'll talk about that in a sec. 1654 01:18:10,430 --> 01:18:11,065 Yeah. 1655 01:18:11,065 --> 01:18:15,270 >> STUDENT 81: The way I thought of it was you needed print it out-- 1656 01:18:15,270 --> 01:18:15,490 >> JASON HIRSCHHORN: Wait. 1657 01:18:15,490 --> 01:18:17,580 Don't tell us what you did. 1658 01:18:17,580 --> 01:18:20,620 We're going to talk in logic. 1659 01:18:20,620 --> 01:18:21,870 >> STUDENT 81: OK. 1660 01:18:21,870 --> 01:18:25,090 1661 01:18:25,090 --> 01:18:27,410 What was the question? 1662 01:18:27,410 --> 01:18:28,892 >> JASON HIRSCHHORN: You just raised your hand. 1663 01:18:28,892 --> 01:18:31,600 There was no question. 1664 01:18:31,600 --> 01:18:32,520 Let me present it. 1665 01:18:32,520 --> 01:18:34,560 Let me just discuss this briefly. 1666 01:18:34,560 --> 01:18:38,400 So we have one pixel, we want to replicate it, both horizontally and 1667 01:18:38,400 --> 01:18:39,360 vertically. 1668 01:18:39,360 --> 01:18:48,920 So ideally what we do here is, we read in our pixel, we write it 1669 01:18:48,920 --> 01:18:51,690 however many of times. 1670 01:18:51,690 --> 01:18:54,720 >> But then we have our trick here, because then we want to skip to the 1671 01:18:54,720 --> 01:18:57,660 next line and write it at the beginning of the next line. 1672 01:18:57,660 --> 01:19:02,960 So if we want to replicate both horizontally and vertically, what is 1673 01:19:02,960 --> 01:19:05,050 one good way to do that-- 1674 01:19:05,050 --> 01:19:06,780 one good though to do that? 1675 01:19:06,780 --> 01:19:11,950 So we don't need to constantly seek around our file to place the things. 1676 01:19:11,950 --> 01:19:14,360 >> That question might not have made sense, but I think an 1677 01:19:14,360 --> 01:19:15,800 answer to it will help. 1678 01:19:15,800 --> 01:19:17,210 >> STUDENT 82: Create an array? 1679 01:19:17,210 --> 01:19:20,090 >> JASON HIRSCHHORN: So let's think of each file as a row. 1680 01:19:20,090 --> 01:19:22,550 Let's think in terms of rows. 1681 01:19:22,550 --> 01:19:26,670 If we have our first row from our small picture, we can make that row 1682 01:19:26,670 --> 01:19:30,640 into a large row from a large picture, and then replicate that row however 1683 01:19:30,640 --> 01:19:34,250 many times it needs to be replicated, rather than going pixel by pixel, 1684 01:19:34,250 --> 01:19:37,260 which gets confusing when dealing with files. 1685 01:19:37,260 --> 01:19:38,730 >> Because if we had-- 1686 01:19:38,730 --> 01:19:41,260 I'm running out of space. 1687 01:19:41,260 --> 01:19:46,490 If this is our file, and we have that one pixel there, and we want to put it 1688 01:19:46,490 --> 01:19:49,840 right there, we still have some things that need to go over there when we're 1689 01:19:49,840 --> 01:19:51,450 writing and creating our new file-- 1690 01:19:51,450 --> 01:19:53,250 our file that's twice as big. 1691 01:19:53,250 --> 01:19:56,820 >> But it's really hard with file functions to skip around to new lines 1692 01:19:56,820 --> 01:20:00,260 like that, and then go back here and put things in there. 1693 01:20:00,260 --> 01:20:04,500 It's almost impossible to do something like that, if that makes sense. 1694 01:20:04,500 --> 01:20:10,180 So if we think in terms of rows, we can take our row, and then put it-- 1695 01:20:10,180 --> 01:20:11,720 replicate rows vertically. 1696 01:20:11,720 --> 01:20:15,860 >> And that's how we deal with resizing vertically rather than horizontally. 1697 01:20:15,860 --> 01:20:18,810 That was kind of quick, and a little confusing. 1698 01:20:18,810 --> 01:20:22,375 Unfortunately our time is up. 1699 01:20:22,375 --> 01:20:27,340 I will stand outside for those of you here who have questions about the 1700 01:20:27,340 --> 01:20:30,500 problem set, including recover. 1701 01:20:30,500 --> 01:20:32,320 >> So let's adjourn for now. 1702 01:20:32,320 --> 01:20:34,480 And again, if you have any questions, we can chat outside. 1703 01:20:34,480 --> 01:20:38,294