1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [AFSNIT 5: mindre behagelig] 2 00:00:02,730 --> 00:00:05,180 [Nate Hardison, Harvard University] 3 00:00:05,180 --> 00:00:08,260 [Dette er CS50.] [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Så velkommen tilbage, gutter. 5 00:00:11,690 --> 00:00:16,320 Velkommen til punkt 5. 6 00:00:16,320 --> 00:00:20,220 På dette tidspunkt, har afsluttet quiz 0 og efter at have set, hvordan du har gjort 7 00:00:20,220 --> 00:00:25,770 forhåbentlig du føler virkelig godt, fordi jeg var meget imponeret over de scorer i dette afsnit. 8 00:00:25,770 --> 00:00:28,050 For vores online seere, vi har haft et par spørgsmål 9 00:00:28,050 --> 00:00:33,680 om de sidste to problemer på det problem sæt - eller på quiz, snarere. 10 00:00:33,680 --> 00:00:39,690 Så vi kommer til at gå over dem virkelig hurtigt, så alle ser hvad der skete 11 00:00:39,690 --> 00:00:45,060 og hvordan man kan gå gennem den faktiske løsning snarere end blot at se løsningen selv. 12 00:00:45,060 --> 00:00:50,330 Vi vil gå over de sidste par problemer virkelig hurtigt, 32 og 33. 13 00:00:50,330 --> 00:00:53,240 Just, igen, kan så at de online seere se dette. 14 00:00:53,240 --> 00:00:59,080 >> Hvis du slår til dit problem 32, som er på side 13, 15 00:00:59,080 --> 00:01:02,730 13 ud af 16, problem 32 handler om swaps. 16 00:01:02,730 --> 00:01:05,010 Det var alt om at bytte to heltal. 17 00:01:05,010 --> 00:01:08,740 Det er det problem, at vi var gået over et par gange i forelæsning. 18 00:01:08,740 --> 00:01:13,590 Og her er, hvad vi beder dig om at gøre en hurtig hukommelse spor. 19 00:01:13,590 --> 00:01:17,000 At udfylde værdierne af variablerne, som de er på stakken 20 00:01:17,000 --> 00:01:20,250 som koden går gennem denne swap-funktion. 21 00:01:20,250 --> 00:01:24,500 Især vi, hvad kigger på - jeg vil sætte denne iPad ned - 22 00:01:24,500 --> 00:01:29,650 i særdeleshed, er det, vi ser på denne linje nummereret 6 lige her. 23 00:01:29,650 --> 00:01:36,740 Og det er nummereret 6 for bare sammenfletningen med den tidligere problem. 24 00:01:36,740 --> 00:01:41,720 Hvad vi ønsker at gøre, er at vise eller mærke tilstand af hukommelse 25 00:01:41,720 --> 00:01:46,090 da det er på det tidspunkt, hvor vi udfører denne linje nummer 6, 26 00:01:46,090 --> 00:01:52,540 der er faktisk en tilbagevenden fra vores swap-funktion lige her. 27 00:01:52,540 --> 00:01:59,450 Hvis vi rulle ned her, så vi, at adresserne på alt i hukommelsen blev leveret for os. 28 00:01:59,450 --> 00:02:02,540 Dette er meget vigtig, og vi vil vende tilbage til det i bare et øjeblik. 29 00:02:02,540 --> 00:02:09,240 Og så hernede på bunden, havde vi en lille hukommelse diagram, som vi kommer til at referere til. 30 00:02:09,240 --> 00:02:12,490 Jeg har faktisk gjort det ud på min iPad. 31 00:02:12,490 --> 00:02:20,720 Så jeg har tænkt mig at skifte frem og tilbage mellem iPad og denne kode bare for reference. 32 00:02:20,720 --> 00:02:26,540 >> Lad os starte. Først, lad os fokusere på de første par linjer af main lige her. 33 00:02:26,540 --> 00:02:30,220 Hvis du vil starte, vi kommer til at initialisere x til 1 og y til 2. 34 00:02:30,220 --> 00:02:33,040 Så vi har to heltalsvariabler, er de begge kommer til at blive placeret på stakken. 35 00:02:33,040 --> 00:02:36,050 Vi kommer til at sætte en 1 og en 2 i dem. 36 00:02:36,050 --> 00:02:43,150 Så hvis jeg vende over til min iPad, forhåbentlig, lad os se - 37 00:02:43,150 --> 00:02:48,660 Apple TV spejling, og der går vi. Okay. 38 00:02:48,660 --> 00:02:51,670 Så hvis jeg vende over til min iPad, 39 00:02:51,670 --> 00:02:56,220 Jeg vil initialisere x til 1 og y til 2. 40 00:02:56,220 --> 00:03:00,580 Det gør vi ganske enkelt ved at skrive en 1 i rubrikken x 41 00:03:00,580 --> 00:03:07,730 og en 2 i rubrikken y. Forholdsvis enkel. 42 00:03:07,730 --> 00:03:11,620 Så nu lad os gå tilbage til den bærbare computer, se hvad der sker næste. 43 00:03:11,620 --> 00:03:15,810 Så dette næste linje er, hvor tingene bliver tricky. 44 00:03:15,810 --> 00:03:28,110 Vi passerer adressen på x og adressen på y som parametrene a og b til swap-funktionen. 45 00:03:28,110 --> 00:03:32,380 Adressen på x og adressen på y er ting, som vi ikke kan beregne 46 00:03:32,380 --> 00:03:36,360 uden at henvise til disse punkttegn lige hernede. 47 00:03:36,360 --> 00:03:39,750 Og heldigvis, de to første punkttegn fortælle os præcis, hvad svarene er. 48 00:03:39,750 --> 00:03:44,740 Adressen på x i hukommelsen er 10, og adressen på y i hukommelsen er 14. 49 00:03:44,740 --> 00:03:51,870 Så det er de værdier, der bliver vedtaget i som a og b op top i vores swap-funktion. 50 00:03:51,870 --> 00:04:00,760 Så igen, skifte tilbage til vores diagram, kan jeg skrive en 10 i en 51 00:04:00,760 --> 00:04:07,400 og en 14 i b. 52 00:04:07,400 --> 00:04:11,610 Nu, dette punkt er, hvor vi gå videre med swap. 53 00:04:11,610 --> 00:04:14,520 Så flipping tilbage til den bærbare computer igen, 54 00:04:14,520 --> 00:04:21,079 vi se, at den måde swappen værker er jeg først dereference en og gemme resultatet i tmp. 55 00:04:21,079 --> 00:04:27,650 Så dereference operatør siger: "Hey. Behandl indholdet af variabel en som en adresse. 56 00:04:27,650 --> 00:04:33,830 Gå til det, der er lagret på den pågældende adresse, og indlæse den. " 57 00:04:33,830 --> 00:04:41,720 Hvad du lægger ud af variablen vil blive gemt i vores tmp variabel. 58 00:04:41,720 --> 00:04:45,150 Flipping tilbage til iPad. 59 00:04:45,150 --> 00:04:51,690 Hvis vi går til Adresse: 10, vi ved, at adressen 10 er det varible x 60 00:04:51,690 --> 00:04:55,480 fordi vi fik at vide af vores kugle punkt, at adressen på x i hukommelsen er 10. 61 00:04:55,480 --> 00:05:00,180 Så vi kan gå der, få værdien af ​​det, som er 1, som vi ser på vores iPad, 62 00:05:00,180 --> 00:05:06,300 og indlæse det i tmp. 63 00:05:06,300 --> 00:05:08,250 Igen, dette er ikke det endelige indhold. 64 00:05:08,250 --> 00:05:14,350 Vi vil gå igennem, og vi vil komme til vores endelige udformning af programmet ved udgangen. 65 00:05:14,350 --> 00:05:17,210 Men lige nu har vi værdien 1 gemmes i tmp. 66 00:05:17,210 --> 00:05:19,210 >> Og der er et hurtigt spørgsmål herovre. 67 00:05:19,210 --> 00:05:23,980 [Alexander] Er dereference operatør - det er bare den stjerne lige foran variablen? 68 00:05:23,980 --> 00:05:27,600 >> Ja. Så dereference operatør, da vi vende tilbage til vores bærbare igen, 69 00:05:27,600 --> 00:05:33,780 er denne stjerne lige foran. 70 00:05:33,780 --> 00:05:37,460 I den forstand er det - du kontrast det med multiplikation operatør 71 00:05:37,460 --> 00:05:42,400 der kræver to ting, den dereference operatør er en Monadiske operatør. 72 00:05:42,400 --> 00:05:46,130 Blot anvendes på en værdi i modsætning til en binær operator, 73 00:05:46,130 --> 00:05:48,810 hvor du anvender til to forskellige værdier. 74 00:05:48,810 --> 00:05:52,080 Så det er hvad der sker i denne linje. 75 00:05:52,080 --> 00:05:58,390 Vi indlæst værdien 1 og gemt det i vores midlertidige heltalsvariabel. 76 00:05:58,390 --> 00:06:05,800 Den næste linje, vi gemme indholdet af b ind - 77 00:06:05,800 --> 00:06:12,630 eller rettere, vi gemme indholdet at b peger på i det sted, hvor en peger på. 78 00:06:12,630 --> 00:06:17,690 Hvis vi analyserer dette fra højre til venstre, vil vi dereference b, 79 00:06:17,690 --> 00:06:23,580 vi kommer til at tage 14, vil vi få fat i heltal, der er der, 80 00:06:23,580 --> 00:06:26,900 og så vil vi gå til adressen 10, 81 00:06:26,900 --> 00:06:34,240 og vi kommer til at kaste et resultat af vores dereference af b ind i dette rum. 82 00:06:34,240 --> 00:06:40,080 Spejlvende tilbage til vores iPad, hvor vi kan gøre dette til en lidt mere konkret, 83 00:06:40,080 --> 00:06:44,070 det måske ville hjælpe, hvis jeg skriver tal på alle de adresser her. 84 00:06:44,070 --> 00:06:53,820 Så vi ved, at y, vi er på adressen 14, x er på adressen 10. 85 00:06:53,820 --> 00:07:00,180 Når vi starter på b, vi dereference b, vil vi få fat i værdien 2. 86 00:07:00,180 --> 00:07:08,320 Vi vil få fat i denne værdi, fordi det er den værdi, der bor på adressen 14. 87 00:07:08,320 --> 00:07:15,700 Og vi vil sætte det i variabel, der bor på adressen 10, 88 00:07:15,700 --> 00:07:19,160 der er lige der, svarende til vore variable x. 89 00:07:19,160 --> 00:07:21,810 Så vi kan gøre en lille smule for at overskrive her 90 00:07:21,810 --> 00:07:35,380 hvor vi slippe af med vores 1 og i stedet skriver vi en 2. 91 00:07:35,380 --> 00:07:39,560 Så alle er meget godt i verden, selv om vi har overskrevne x nu. 92 00:07:39,560 --> 00:07:44,890 Vi har gemt x gamle værdi i vores tmp variabel. 93 00:07:44,890 --> 00:07:50,210 Så vi kan færdiggøre ombytningen med den næste linje. 94 00:07:50,210 --> 00:07:53,030 Spejlvende tilbage til vores bærbare. 95 00:07:53,030 --> 00:07:58,150 Nu er alt der er tilbage er at tage indholdet ud af vores midlertidige heltalsvariabel 96 00:07:58,150 --> 00:08:05,630 og gemme dem i den variabel, der bor på den adresse, b holder. 97 00:08:05,630 --> 00:08:10,230 Så vi vil til effektivt at dereference b for at få adgang til den variable 98 00:08:10,230 --> 00:08:14,340 det er på den adresse, b besidder i det, 99 00:08:14,340 --> 00:08:19,190 og vi vil proppe den værdi, tmp holder ind i det. 100 00:08:19,190 --> 00:08:23,280 Flipping tilbage til iPad igen. 101 00:08:23,280 --> 00:08:31,290 Jeg kan slette denne værdi her, 2, 102 00:08:31,290 --> 00:08:41,010 og i stedet vil vi kopiere 1 højre ind i det. 103 00:08:41,010 --> 00:08:43,059 Så den næste linje, der udfører, naturligvis - 104 00:08:43,059 --> 00:08:47,150 hvis vi vende tilbage til den bærbare computer - er dette punkt 6, 105 00:08:47,150 --> 00:08:52,500 som er det punkt, hvor vi ønskede at have vores diagram helt fyldt ud. 106 00:08:52,500 --> 00:08:58,940 Så flipping tilbage til iPad igen, bare så du kan se det færdige diagram, 107 00:08:58,940 --> 00:09:06,610 du kan se, at vi har en 10 i en, en 14 i b, en 1 tmp, 2 i x, og en 1 i y. 108 00:09:06,610 --> 00:09:11,000 Er der nogen spørgsmål om dette? 109 00:09:11,000 --> 00:09:14,640 Giver det mere mening, efter at have gået igennem det? 110 00:09:14,640 --> 00:09:24,850 Gør mindre mening? Forhåbentlig ikke. Okay. 111 00:09:24,850 --> 00:09:28,230 >> Pointers er en meget tricky emne. 112 00:09:28,230 --> 00:09:33,420 En af fyrene vi arbejder med har et meget almindeligt ordsprog: 113 00:09:33,420 --> 00:09:36,590 "For at forstå pegepinde, skal du først forstå pointers." 114 00:09:36,590 --> 00:09:40,530 Hvilket jeg synes er meget sandt. Det tager et stykke tid at vænne sig til det. 115 00:09:40,530 --> 00:09:45,360 Tegning masser af billeder, trækker masser af hukommelse diagrammer som denne meget nyttigt, 116 00:09:45,360 --> 00:09:49,480 og når du går igennem eksempel efter eksempel efter eksempel, 117 00:09:49,480 --> 00:09:54,450 det vil begynde at gøre lidt mere mening og lidt mere fornuft og lidt mere mening. 118 00:09:54,450 --> 00:10:01,560 Endelig en dag, vil du have det hele helt mestrer. 119 00:10:01,560 --> 00:10:13,800 Eventuelle spørgsmål før vi går videre til det næste problem? Ok. 120 00:10:13,800 --> 00:10:18,840 Så vende tilbage til den bærbare computer. 121 00:10:18,840 --> 00:10:23,300 Det næste problem, vi har, er problem nummer 33 på fil I / O. 122 00:10:23,300 --> 00:10:26,350 Zoom ind på dette en lille smule. 123 00:10:26,350 --> 00:10:28,710 Problem 33 - Ja? 124 00:10:28,710 --> 00:10:32,110 >> [Daniel] Jeg har lige haft et hurtigt spørgsmål. Denne stjerne, eller stjernen, 125 00:10:32,110 --> 00:10:35,590 det hedder dereferere, når du bruger en stjerne før. 126 00:10:35,590 --> 00:10:38,820 Hvad kaldes det, når du bruger tegnet før? 127 00:10:38,820 --> 00:10:43,140 >> Tegnet før er adressen-of operatør. 128 00:10:43,140 --> 00:10:45,880 Så lad os rulle tilbage op. 129 00:10:45,880 --> 00:10:49,310 Ups. Jeg er i zoom-mode, så jeg kan ikke rigtig rulle. 130 00:10:49,310 --> 00:10:52,780 Hvis vi ser på denne kode virkelig hurtigt lige her, 131 00:10:52,780 --> 00:10:54,980 igen, samme ting sker. 132 00:10:54,980 --> 00:10:59,180 Hvis vi ser på denne kode lige her, på denne linje, hvor vi foretager opkaldet til at bytte, 133 00:10:59,180 --> 00:11:10,460 tegnet er bare at sige "få den adresse, hvor variable x liv." 134 00:11:10,460 --> 00:11:14,460 Når din compiler kompilerer din kode, 135 00:11:14,460 --> 00:11:20,590 det skal rent fysisk afmærke en plads i hukommelsen for alle dine variabler til at leve. 136 00:11:20,590 --> 00:11:24,910 Og hvad så compileren kan så gøre når den er kompileret alt, 137 00:11:24,910 --> 00:11:31,110 det ved, "Åh, jeg sætter x på adressen 10. Jeg sætter y på adressen 14." 138 00:11:31,110 --> 00:11:34,640 Det kan derefter udfylde disse værdier for dig. 139 00:11:34,640 --> 00:11:44,740 Så du kan da - det kan så videregive denne i og pass & y i så godt. 140 00:11:44,740 --> 00:11:50,730 Disse fyre få adressen, men de har også, når du passerer dem i swap-funktion, 141 00:11:50,730 --> 00:11:55,690 denne type information, denne int * lige her, fortæller compileren, 142 00:11:55,690 --> 00:12:01,350 "Okay, vi kommer til at fortolke denne adresse som en adresse på en heltalsvariabel." 143 00:12:01,350 --> 00:12:05,900 Som en adresse på en int, er der forskellig fra adressen på et tegn variabel 144 00:12:05,900 --> 00:12:09,930 fordi en int optager, på en 32-bit maskine, fylder 4 bytes af rummet, 145 00:12:09,930 --> 00:12:13,310 hvorimod en karakter tager kun op 1 byte plads. 146 00:12:13,310 --> 00:12:17,310 Så det er vigtigt at vide, også hvad der er - hvad bor, hvilken type værdi 147 00:12:17,310 --> 00:12:20,340 bor på den adresse, der fik gået i. 148 00:12:20,340 --> 00:12:22,020 Eller den adresse, du har at gøre med. 149 00:12:22,020 --> 00:12:29,020 På den måde ved du, hvor mange bytes af information til rent faktisk at indlæse ud af din RAM. 150 00:12:29,020 --> 00:12:31,780 Og så, ja, blev denne dereference operatør, ligesom du spørger, 151 00:12:31,780 --> 00:12:37,200 går og adgang til oplysninger på en bestemt adresse. 152 00:12:37,200 --> 00:12:42,820 Så den står, med en variabel her, behandle indholdet af en som en adresse, 153 00:12:42,820 --> 00:12:47,880 gå til denne adresse, og trække ud, indlæse i processoren, belastning i et register 154 00:12:47,880 --> 00:12:56,340 de faktiske værdier eller indholdet, der lever på denne adresse. 155 00:12:56,340 --> 00:12:59,620 Flere spørgsmål? Det er gode spørgsmål. 156 00:12:59,620 --> 00:13:01,650 Det er en masse ny terminologi også. 157 00:13:01,650 --> 00:13:09,800 Det er også lidt funky, ser & og * i forskellige steder. 158 00:13:09,800 --> 00:13:13,180 >> Ok. 159 00:13:13,180 --> 00:13:18,530 Så tilbage til problem 33, fil I / O. 160 00:13:18,530 --> 00:13:22,540 Dette var et af de problemer, som jeg tror et par ting der skete. 161 00:13:22,540 --> 00:13:25,400 En, det er en temmelig nyt emne. 162 00:13:25,400 --> 00:13:30,590 Det blev fremlagt meget snart før quiz, 163 00:13:30,590 --> 00:13:33,400 og så tror jeg, det var lidt ligesom en af ​​disse ord problemer i matematik 164 00:13:33,400 --> 00:13:39,720 hvor de giver dig en masse oplysninger, men du faktisk ikke ender med at skulle bruge et ton af det. 165 00:13:39,720 --> 00:13:44,060 Den første del af dette problem er at beskrive, hvad en CSV-fil er. 166 00:13:44,060 --> 00:13:50,620 Nu, en CSV-fil, ifølge beskrivelsen, er en kommasepareret værdier fil. 167 00:13:50,620 --> 00:13:55,300 Grunden til disse overhovedet er interessante, og grunden til at du nogensinde bruge dem, 168 00:13:55,300 --> 00:14:00,800 er, fordi, hvor mange af jer nogensinde brugt ting som Excel? 169 00:14:00,800 --> 00:14:03,240 Figur fleste af jer har, sandsynligvis, vil eller bruge på et tidspunkt i dit liv. 170 00:14:03,240 --> 00:14:06,430 Du skal bruge noget som Excel. 171 00:14:06,430 --> 00:14:10,940 For at få de data ud af et Excel-regneark eller gøre nogen form for behandling med det, 172 00:14:10,940 --> 00:14:17,240 hvis du ønsker at skrive et C-program eller Python program, Java-program, 173 00:14:17,240 --> 00:14:20,070 at beskæftige sig med de data, du har gemt derinde, 174 00:14:20,070 --> 00:14:23,170 en af ​​de mest almindelige måder at få det ud er i en CSV-fil. 175 00:14:23,170 --> 00:14:26,850 Og du kan åbne op Excel og når du gå til 'Gem som' dialog, 176 00:14:26,850 --> 00:14:32,840 du kan få en egentlig CSV-fil. 177 00:14:32,840 --> 00:14:35,890 >> Handy til at vide, hvordan man skal håndtere disse ting. 178 00:14:35,890 --> 00:14:42,010 Den måde det virker er, at det ligner - jeg mener, det er væsentligt at efterligne et regneark, 179 00:14:42,010 --> 00:14:47,590 når der, som vi ser her, i den meget venstre-mest stykke, 180 00:14:47,590 --> 00:14:49,910 vi har alle de sidste navne. 181 00:14:49,910 --> 00:14:54,670 Så vi har Malan, så Hardison, og derefter Bowden, MacWilliam, og derefter Chan. 182 00:14:54,670 --> 00:14:59,470 Alle de sidste navne. Og så et komma adskiller de sidste navne fra de første navne. 183 00:14:59,470 --> 00:15:02,970 David, Nate, Rob, Tommy, og Zamyla. 184 00:15:02,970 --> 00:15:06,850 Jeg har altid blande Robby og Tom. 185 00:15:06,850 --> 00:15:10,940 Og så, endelig, den tredje kolonne er e-mail adresser. 186 00:15:10,940 --> 00:15:18,500 Når du forstår det, resten af ​​programmet er forholdsvis ligetil at gennemføre. 187 00:15:18,500 --> 00:15:23,850 Hvad vi har gjort, for at efterligne dette samme struktur i vores C-program 188 00:15:23,850 --> 00:15:27,510 er vi har brugt en struktur. 189 00:15:27,510 --> 00:15:30,520 Vi begynder at spille med disse lidt mere så godt. 190 00:15:30,520 --> 00:15:35,790 Vi så dem for første lidt i problemer sæt 3, da vi beskæftiger sig med ordbøger. 191 00:15:35,790 --> 00:15:40,290 Men dette personale struct gemmer et efternavn, et fornavn, og en e-mail. 192 00:15:40,290 --> 00:15:44,500 Ligesom vores CSV fil blev lagring. 193 00:15:44,500 --> 00:15:47,950 Så dette er blot konvertere fra et format til et andet. 194 00:15:47,950 --> 00:15:54,630 Vi er nødt til at konvertere, i dette tilfælde, en ansat struct i en linje, 195 00:15:54,630 --> 00:15:59,060 en kommasepareret linje, ligesom det. 196 00:15:59,060 --> 00:16:01,500 Giver det mening? I gutter har alle taget quizzen, 197 00:16:01,500 --> 00:16:07,680 så jeg forestille mig, du har i det mindste haft lidt tid til at tænke over dette. 198 00:16:07,680 --> 00:16:16,410 >> I leje-funktionen, spørger problem for os at tage på - we'll zoome ind på dette en lille smule - 199 00:16:16,410 --> 00:16:22,480 tage i en personale struktur, et personale struct, med navn s, 200 00:16:22,480 --> 00:16:30,900 og tilføje indholdet til vores staff.csv fil. 201 00:16:30,900 --> 00:16:34,230 Det viser sig, at dette er forholdsvis ligetil at bruge. 202 00:16:34,230 --> 00:16:37,430 Vi slags lege med disse funktioner lidt mere i dag. 203 00:16:37,430 --> 00:16:44,510 Men i dette tilfælde, er det fprintf funktion virkelig nøglen. 204 00:16:44,510 --> 00:16:51,960 Så med fprintf, kan vi udskrive, ligesom jer har brugt printf hele denne valgperiode. 205 00:16:51,960 --> 00:16:55,050 Man kan printf en linje til en fil. 206 00:16:55,050 --> 00:16:59,030 Så i stedet for bare at gøre den sædvanlige printf opkald, hvor du give det format string 207 00:16:59,030 --> 00:17:05,380 og så skal du erstatte alle de variabler med følgende argumenter, 208 00:17:05,380 --> 00:17:11,290 med fprintf, er din allerførste argument i stedet den fil, du vil skrive til. 209 00:17:11,290 --> 00:17:21,170 Hvis vi skulle til at se på dette i apparatet, for eksempel, mand fprintf, 210 00:17:21,170 --> 00:17:25,980 kan vi se forskellen mellem printf og fprintf. 211 00:17:25,980 --> 00:17:28,960 Jeg zoome ind her en lille smule. 212 00:17:28,960 --> 00:17:33,140 Så med printf, giver vi det et format streng, og derefter de efterfølgende argumenter 213 00:17:33,140 --> 00:17:37,580 er alle de variabler for udskiftning eller substitution ind i vores formatstreng. 214 00:17:37,580 --> 00:17:47,310 Betragtninger med fprintf, er det første argument faktisk denne fil * kaldes en strøm. 215 00:17:47,310 --> 00:17:51,800 >> Flytning tilbage herovre til vores leje, 216 00:17:51,800 --> 00:17:54,550 Vi har allerede fået vores fil * stream åbnet for os. 217 00:17:54,550 --> 00:17:57,810 Det er, hvad denne første linje gør, det åbner staff.csv filen, 218 00:17:57,810 --> 00:18:01,690 den åbner det i append mode, og alle, der er tilbage for os at gøre, er 219 00:18:01,690 --> 00:18:08,640 skriver personalet struktur til filen. 220 00:18:08,640 --> 00:18:10,870 Og, lad os se, jeg ønsker at bruge iPad? 221 00:18:10,870 --> 00:18:17,900 Jeg vil bruge iPad. Vi har ugyldige - lad os sætte dette på bordet, så jeg kan skrive lidt bedre - 222 00:18:17,900 --> 00:18:33,680 ugyldig leje og det tager i ét argument, et personale struktur, der kaldes s. 223 00:18:33,680 --> 00:18:44,120 Fik vores seler, har vi fået vores fil * kaldet fil, 224 00:18:44,120 --> 00:18:48,380 vi har vores fopen linje givet os, 225 00:18:48,380 --> 00:18:51,890 og jeg vil bare skrive det som prikker da det er allerede i pedia. 226 00:18:51,890 --> 00:19:00,530 Og så på vores næste linje, vi kommer til at foretage et opkald til fprintf 227 00:19:00,530 --> 00:19:03,700 og vi kommer til at passere i den fil, vi ønsker at udskrive til, 228 00:19:03,700 --> 00:19:10,290 og derefter vores formatstreng, som - 229 00:19:10,290 --> 00:19:14,300 Jeg vil lade jer fortælle mig, hvad det ligner. 230 00:19:14,300 --> 00:19:20,500 Hvad med dig,? Stella Ved du, hvad den første del af formatstreng ser ud? 231 00:19:20,500 --> 00:19:24,270 [Stella] Jeg er ikke sikker. >> Du er velkommen til at spørge Jimmy. 232 00:19:24,270 --> 00:19:27,690 Kender du, Jimmy? 233 00:19:27,690 --> 00:19:31,000 [Jimmy] Vil det bare være sidst? Det ved jeg ikke. Jeg er ikke helt sikker. 234 00:19:31,000 --> 00:19:39,020 >> Okay. Hvad med, har nogen få dette korrekt på eksamen? 235 00:19:39,020 --> 00:19:41,770 Nej Okay. 236 00:19:41,770 --> 00:19:47,920 Det viser sig, at her alt, hvad vi skal gøre, er at vi ønsker hver del af vores personale struktur 237 00:19:47,920 --> 00:19:53,290 skal printes ud som en streng ind i vores fil. 238 00:19:53,290 --> 00:19:59,900 Vi bare bruge strengen substitution karakter tre forskellige tidspunkter, fordi vi har et efternavn 239 00:19:59,900 --> 00:20:07,160 efterfulgt af komma, og derefter et fornavn efterfulgt af et komma, 240 00:20:07,160 --> 00:20:12,430 og så endelig den e-mailadresse, der er fulgt - hvilket ikke er 241 00:20:12,430 --> 00:20:15,140 montering på min skærm - men det er efterfulgt af en ny linje. 242 00:20:15,140 --> 00:20:20,060 Så jeg har tænkt mig at skrive det bare dernede. 243 00:20:20,060 --> 00:20:23,560 Og så efter vores formatstreng, 244 00:20:23,560 --> 00:20:27,880 vi bare have de substitutioner, som vi har adgang til via den dot-notationen 245 00:20:27,880 --> 00:20:31,370 at vi så i problemet sæt 3. 246 00:20:31,370 --> 00:20:48,820 Vi kan bruge s.last, s.first, og s.email 247 00:20:48,820 --> 00:20:58,990 at erstatte i de tre værdier til vores formatstreng. 248 00:20:58,990 --> 00:21:06,190 Så hvordan gik det? Give mening? 249 00:21:06,190 --> 00:21:09,700 Ja? Nej? Muligvis? Okay. 250 00:21:09,700 --> 00:21:14,180 >> Den sidste ting, som vi gør, når vi har udskrevet, og efter vi har åbnet vores fil: 251 00:21:14,180 --> 00:21:17,370 når vi har åbnet en fil, vi altid skal huske at lukke den. 252 00:21:17,370 --> 00:21:19,430 Fordi vi ellers vil ende op lækker hukommelsen, 253 00:21:19,430 --> 00:21:22,500 bruger op fildeskriptorer. 254 00:21:22,500 --> 00:21:25,950 Så for at lukke det, hvilken funktion bruger vi? Daniel? 255 00:21:25,950 --> 00:21:30,120 [Daniel] fclose? >> Fclose, præcis. 256 00:21:30,120 --> 00:21:37,520 Så den sidste del af dette problem var at korrekt lukke filen ved hjælp af fclose funktion, 257 00:21:37,520 --> 00:21:40,370 der bare ligner det. 258 00:21:40,370 --> 00:21:43,880 Ikke vanvittigt. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Så det er problem 33 på quizzen. 261 00:21:49,520 --> 00:21:52,480 Vi vil have absolut mere fil I / O kommer op. 262 00:21:52,480 --> 00:21:55,130 Vi vil gøre en lille smule mere i foredrag i dag, eller i snit i dag, 263 00:21:55,130 --> 00:22:01,710 fordi det er hvad der kommer til at danne det meste af denne kommende Pset. 264 00:22:01,710 --> 00:22:05,020 Lad os gå videre fra quizzen på dette punkt. Ja? 265 00:22:05,020 --> 00:22:10,880 >> [Charlotte]] Hvorfor fclose (fil) i stedet for fclose (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 >> Ah. Fordi det viser sig, at - så spørgsmålet, hvilket er en stor en, 267 00:22:19,100 --> 00:22:27,800 er grunden til, når vi skriver fclose, er vi skriver fclose (fil) stjerne variabel 268 00:22:27,800 --> 00:22:33,680 i modsætning til filnavnet, staff.csv? Er det korrekt? Yeah. 269 00:22:33,680 --> 00:22:39,570 Så lad os tage et kig. Hvis jeg skifter tilbage til min laptop, 270 00:22:39,570 --> 00:22:45,040 og lad os se på det fclose funktion. 271 00:22:45,040 --> 00:22:51,460 Så det fclose funktion lukker en stream, og det tager i markøren til den strøm, vi ønsker at lukke, 272 00:22:51,460 --> 00:22:57,010 i modsætning til den aktuelle filnavn, som vi ønsker at lukke. 273 00:22:57,010 --> 00:23:01,620 Og det er fordi bag kulisserne, når du foretager et opkald til fopen, 274 00:23:01,620 --> 00:23:12,020 når du åbner en fil, du faktisk tildele hukommelse til at gemme oplysninger om filen. 275 00:23:12,020 --> 00:23:16,380 Så du har fil pointer, der har oplysninger om filen, 276 00:23:16,380 --> 00:23:23,080 såsom det er åbent, dens størrelse, hvor du er i øjeblikket i filen, 277 00:23:23,080 --> 00:23:29,100 så du kan gøre læsning og skrivning opkald til det pågældende sted i filen. 278 00:23:29,100 --> 00:23:38,060 Du ender lukke pointer i stedet for at lukke filnavnet. 279 00:23:38,060 --> 00:23:48,990 >> Ja? [Daniel] Så for at bruge leje, vil du sige - hvordan kan det få brugeren input? 280 00:23:48,990 --> 00:23:53,830 Har fprintf handle som GetString i den forstand, at det bare vil vente på input fra brugeren 281 00:23:53,830 --> 00:23:57,180 og beder dig om at skrive dette - eller vente for dig at skrive disse tre ting i? 282 00:23:57,180 --> 00:24:00,480 Eller har du brug for at bruge noget til at gennemføre leje? 283 00:24:00,480 --> 00:24:04,100 >> Yeah. Så vi er ikke - spørgsmålet var, hvordan vi får input fra brugeren 284 00:24:04,100 --> 00:24:09,220 for at gennemføre leje? Og hvad vi har her, er den, der ringer til leje, 285 00:24:09,220 --> 00:24:17,690 vedtaget i denne personale struct med alle de data, der er lagret i struct allerede. 286 00:24:17,690 --> 00:24:22,990 Så fprintf er i stand til bare skrive disse data direkte til filen. 287 00:24:22,990 --> 00:24:25,690 Der er ingen ventetid for bruger input. 288 00:24:25,690 --> 00:24:32,110 Brugeren har allerede givet input ved korrekt at sætte det i dette personale struct. 289 00:24:32,110 --> 00:24:36,510 Og ting, selvfølgelig, bryde ville, hvis nogen af ​​disse pointers var null, 290 00:24:36,510 --> 00:24:40,370 så vi rulle tilbage op her, og vi ser på vores struct. 291 00:24:40,370 --> 00:24:43,640 Vi har string sidste, string første streng email. 292 00:24:43,640 --> 00:24:48,530 Vi ved nu, at alle dem virkelig, under kølerhjelmen, er char * variable. 293 00:24:48,530 --> 00:24:53,470 Det kan eller ikke kan pege på null. 294 00:24:53,470 --> 00:24:55,800 De kan pege på hukommelse på heapen, 295 00:24:55,800 --> 00:24:59,650 måske hukommelse på stakken. 296 00:24:59,650 --> 00:25:04,580 Vi ved ikke rigtig, men hvis nogen af ​​disse henvisninger er null, eller ugyldigt, 297 00:25:04,580 --> 00:25:08,120 at der vil helt sikkert gå ned vores leje funktion. 298 00:25:08,120 --> 00:25:11,050 Det var noget, der var lidt uden for rammerne af eksamen. 299 00:25:11,050 --> 00:25:16,440 Vi er ikke bekymre sig om det. 300 00:25:16,440 --> 00:25:22,170 Great. Okay. Så vi går videre fra quizzen. 301 00:25:22,170 --> 00:25:25,760 >> Lad os lukke denne fyr, og vi vil se på Pset 4. 302 00:25:25,760 --> 00:25:34,700 Så hvis du fyre ser på Pset spec, når du kan få adgang til det, cs50.net/quizzes, 303 00:25:34,700 --> 00:25:42,730 vi vil gå igennem et par af afsnittet problemer i dag. 304 00:25:42,730 --> 00:25:52,240 Jeg rulle ned - afsnit med spørgsmål begynder på den tredje side af Pset spec. 305 00:25:52,240 --> 00:25:57,800 Og den første del beder dig om at gå og se kort på omdirigere og rør. 306 00:25:57,800 --> 00:26:02,820 Hvilket var lidt af en kølig kort, viser dig nogle nye, seje kommandolinjeflag tricks som du kan bruge. 307 00:26:02,820 --> 00:26:06,050 Og så har vi fået et par spørgsmål til dig så godt. 308 00:26:06,050 --> 00:26:10,860 Denne første spørgsmål om vandløb, som printf skriver som standard, 309 00:26:10,860 --> 00:26:15,920 vi slags inde på bare en lille smule for et øjeblik siden. 310 00:26:15,920 --> 00:26:22,380 Denne fprintf at vi bare diskuterede tager i en fil * strøm som argument. 311 00:26:22,380 --> 00:26:26,580 fclose tager i en fil * strøm så godt, 312 00:26:26,580 --> 00:26:32,660 og returværdien af ​​fopen giver dig en fil * strøm så godt. 313 00:26:32,660 --> 00:26:36,060 Grunden til at vi ikke har set dem før, når vi har behandlet printf 314 00:26:36,060 --> 00:26:39,450 er fordi printf har en standard stream. 315 00:26:39,450 --> 00:26:41,810 Og den standard strøm, som den skriver 316 00:26:41,810 --> 00:26:45,190 du vil finde ud af om der på kort. 317 00:26:45,190 --> 00:26:50,080 Så helt sikkert tage et kig på det. 318 00:26:50,080 --> 00:26:53,010 >> I dagens afsnit vil vi snakke lidt om GDB, 319 00:26:53,010 --> 00:26:57,720 eftersom den mere velkendte du er med det, jo mere praksis, du får med det, 320 00:26:57,720 --> 00:27:01,390 det bedre i stand du vil være rent faktisk at jagte fejl i din egen kode. 321 00:27:01,390 --> 00:27:05,540 Det fremskynder processen med debugging op voldsomt. 322 00:27:05,540 --> 00:27:09,230 Så ved hjælp af printf, hver gang du gør, at du er nødt til at kompilere din kode, 323 00:27:09,230 --> 00:27:13,000 du er nødt til at køre det igen, nogle gange er du nødt til at flytte printf opkald rundt, 324 00:27:13,000 --> 00:27:17,100 udkommentere kode, det bare tager et stykke tid. 325 00:27:17,100 --> 00:27:20,850 Vores mål er at forsøge at overbevise dig om, at med GDB, kan du hovedsageligt 326 00:27:20,850 --> 00:27:26,810 printf noget på noget tidspunkt i din kode, og du aldrig behøver at kompilere det. 327 00:27:26,810 --> 00:27:35,120 Du behøver aldrig at starte og holde gætte hvor skal printf næste. 328 00:27:35,120 --> 00:27:40,910 Den første ting at gøre, er at kopiere denne linje og få afsnitskendetegnet ud af banen. 329 00:27:40,910 --> 00:27:47,530 Jeg kopiere denne linje kode, der siger, "wget ​​http://cdn.cs50.net". 330 00:27:47,530 --> 00:27:49,510 Jeg har tænkt mig at kopiere den. 331 00:27:49,510 --> 00:27:55,950 Jeg har tænkt mig at gå over til min apparat, zoome ud, så du kan se, hvad jeg gør, 332 00:27:55,950 --> 00:28:01,890 indsætte det i der, og når jeg trykker på Enter, denne wget kommando bogstaveligt er et web får. 333 00:28:01,890 --> 00:28:06,210 Det kommer til at trække ned denne fil ud af internettet, 334 00:28:06,210 --> 00:28:11,790 og det kommer til at gemme den til den aktuelle mappe. 335 00:28:11,790 --> 00:28:21,630 Nu hvis jeg liste min nuværende bibliotek kan du se, at jeg har fået denne section5.zip fil derinde. 336 00:28:21,630 --> 00:28:25,260 Den måde at beskæftige sig med den fyr, er at pakke den, 337 00:28:25,260 --> 00:28:27,650 som du kan gøre i kommandolinjen, ligesom dette. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Det vil unzip det, skal du oprette mappen for mig, 340 00:28:36,980 --> 00:28:40,410 oppuste hele indholdet, sætte dem derinde. 341 00:28:40,410 --> 00:28:47,410 Så nu kan jeg gå ind i mit afsnit 5 mappe ved hjælp af kommandoen cd. 342 00:28:47,410 --> 00:28:58,310 Ryd skærmen med tydelig. Så rydde skærmen. 343 00:28:58,310 --> 00:29:02,280 Nu har jeg fået en dejlig ren terminal at beskæftige sig med. 344 00:29:02,280 --> 00:29:06,200 >> Nu, hvis jeg en liste over alle de filer, som jeg ser i denne mappe, 345 00:29:06,200 --> 00:29:12,270 du se, at jeg har fire filer: buggy1, buggy2, buggy3 og buggy4. 346 00:29:12,270 --> 00:29:16,180 Jeg har også fået deres tilsvarende. C-filer. 347 00:29:16,180 --> 00:29:20,400 Vi kommer ikke til at se på de. C-filer for nu. 348 00:29:20,400 --> 00:29:24,140 I stedet vil vi bruge dem, når vi åbner op GDB. 349 00:29:24,140 --> 00:29:28,220 Vi har holdt dem rundt, så vi har adgang til den egentlige kilde kode, når vi bruger GDB, 350 00:29:28,220 --> 00:29:32,740 men målet for denne del af afsnittet er at pille rundt med GDB 351 00:29:32,740 --> 00:29:40,370 og se, hvordan vi kan bruge det til at finde ud af, hvad der går galt med hver af disse fire buggy programmer. 352 00:29:40,370 --> 00:29:43,380 Så vi vil bare rundt i lokalet virkelig hurtigt, 353 00:29:43,380 --> 00:29:47,000 og jeg har tænkt mig at spørge nogen til at køre en af ​​de buggy programmer, 354 00:29:47,000 --> 00:29:54,730 og så vil vi gå som en gruppe gennem GDB, og vi vil se hvad vi kan gøre for at løse disse programmer, 355 00:29:54,730 --> 00:29:58,460 eller i det mindste identificere, hvad der går galt i hver af dem. 356 00:29:58,460 --> 00:30:04,760 Lad os starte forfra her med Daniel. Vil du køre buggy1? Lad os se hvad der sker. 357 00:30:04,760 --> 00:30:09,470 [Daniel] Det siger, at der er et program fejl. >> Yeah. Præcis. 358 00:30:09,470 --> 00:30:12,460 Så hvis jeg løber buggy1, får jeg en seg fejl. 359 00:30:12,460 --> 00:30:16,210 På dette tidspunkt kunne jeg gå og åbne op buggy1.c, 360 00:30:16,210 --> 00:30:19,450 forsøge at finde ud af, hvad der går galt, 361 00:30:19,450 --> 00:30:22,000 men en af ​​de mest ubehagelige ting om dette seg fejl fejl 362 00:30:22,000 --> 00:30:27,610 er, at det ikke fortæller dig om, hvad linje af programmets tingene faktisk gik galt og brød. 363 00:30:27,610 --> 00:30:29,880 Du slags nødt til at se på koden 364 00:30:29,880 --> 00:30:33,990 og finde ud af ved hjælp af gæt og tjek eller printf for at se, hvad der går galt. 365 00:30:33,990 --> 00:30:37,840 En af de fedeste ting ved GDB er, at det er virkelig, virkelig nemt 366 00:30:37,840 --> 00:30:42,170 at finde ud af den linje, hvor dit program går ned. 367 00:30:42,170 --> 00:30:46,160 Det er fuldstændig det værd at bruge det, selv om bare for det. 368 00:30:46,160 --> 00:30:56,190 Så til at starte op GDB, jeg skriver GDB, og så giver jeg det stien til den eksekverbare, at jeg vil køre. 369 00:30:56,190 --> 00:31:01,960 Her Jeg skriver gdb ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Hit på Enter. Giver mig alt dette oplysninger om ophavsret, 371 00:31:06,600 --> 00:31:13,000 og hernede du vil se denne linje, der siger, "Reading symboler fra / home / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1. " 373 00:31:17,680 --> 00:31:22,060 Og hvis alt går vel, vil du se det udskrive en besked, der ligner denne. 374 00:31:22,060 --> 00:31:25,500 Det vil læse symboler, vil det sige "Jeg læser symboler fra din eksekverbar fil," 375 00:31:25,500 --> 00:31:29,900 og så vil det have denne "done" budskab herovre. 376 00:31:29,900 --> 00:31:35,410 Hvis du ser en anden variation af dette, eller du kan se kan det ikke finde symbolerne 377 00:31:35,410 --> 00:31:41,460 eller noget lignende, hvad det betyder er, at du bare ikke har kompileret din eksekverbare ordentligt. 378 00:31:41,460 --> 00:31:49,980 Når vi udarbejder programmer til brug med GDB, er vi nødt til at bruge den særlige g flag, 379 00:31:49,980 --> 00:31:54,540 og det er gjort som standard, hvis du kompilere dine programmer, blot ved at skrive make 380 00:31:54,540 --> 00:31:59,320 eller gøre buggy eller gøre inddrive, nogen af ​​dem. 381 00:31:59,320 --> 00:32:07,800 Men hvis du kompilere manuelt med Dunk, så du bliver nødt til at gå ind og omfatte, at-g flag. 382 00:32:07,800 --> 00:32:10,310 >> På dette tidspunkt, at vi nu har vores GDB prompt, 383 00:32:10,310 --> 00:32:12,310 det er ret simpelt at køre programmet. 384 00:32:12,310 --> 00:32:19,740 Vi kan enten skrive løb, eller vi kan blot skrive r. 385 00:32:19,740 --> 00:32:22,820 De fleste GDB kommandoer kan forkortes. 386 00:32:22,820 --> 00:32:25,940 Normalt til blot en eller et par bogstaver, som er temmelig nice. 387 00:32:25,940 --> 00:32:30,980 Så Saad, hvis du skriver r og tryk på Enter, hvad sker der? 388 00:32:30,980 --> 00:32:39,390 [Saad] Jeg fik SIGSEGV, segmentering fejl og derefter alt dette volapyk. 389 00:32:39,390 --> 00:32:43,650 >> Yeah. 390 00:32:43,650 --> 00:32:47,990 Ligesom vi ser på skærmen lige nu, og ligesom Saad sagde, 391 00:32:47,990 --> 00:32:53,430 når vi skriver run eller r og tryk på Enter, vi stadig få den samme seg skyld. 392 00:32:53,430 --> 00:32:55,830 Så ved hjælp GDB løser ikke vores problem. 393 00:32:55,830 --> 00:32:59,120 Men det giver os nogle volapyk, og det viser sig, at denne volapyk 394 00:32:59,120 --> 00:33:03,080 faktisk fortæller os, hvor det sker. 395 00:33:03,080 --> 00:33:10,680 At parse dette en lille smule, denne første bit er den funktion, hvor alting går galt. 396 00:33:10,680 --> 00:33:20,270 Der er denne __ strcmp_sse4_2, og det fortæller os, at det sker i denne fil 397 00:33:20,270 --> 00:33:29,450 kaldet sysdeps/i386, alt dette igen, sådan et rod - men linie 254. 398 00:33:29,450 --> 00:33:31,670 Det er lidt svært at parse. Normalt når du ser ting som dette, 399 00:33:31,670 --> 00:33:38,770 det betyder, at det er seg forkastning i en af ​​systembiblioteker. 400 00:33:38,770 --> 00:33:43,220 Så noget at gøre med strcmp. I gutter har set strcmp før. 401 00:33:43,220 --> 00:33:52,730 Ikke vanvittigt, men betyder det, at strcmp er brudt, eller at der er et problem med strcmp? 402 00:33:52,730 --> 00:33:57,110 Hvad tror du, Alexander? 403 00:33:57,110 --> 00:34:04,890 [Alexander] Er det - er 254 linjen? Og - ikke den binære, men det er ikke deres lofter, 404 00:34:04,890 --> 00:34:10,590 og så er der et andet sprog for hver funktion. Er det 254 i denne funktion, eller -? 405 00:34:10,590 --> 00:34:21,460 >> Det er linie 254. Det ligner i denne. Sagsakter, så det er forsamling kode sandsynligvis. 406 00:34:21,460 --> 00:34:25,949 >> Men jeg gætter på mere presserende ting er, fordi vi har fået en seg fejl, 407 00:34:25,949 --> 00:34:29,960 og det ser ud som det kommer fra den strcmp funktion, 408 00:34:29,960 --> 00:34:38,030 indebærer dette, så er det strcmp brudt? 409 00:34:38,030 --> 00:34:42,290 Det skal ikke, forhåbentlig. Så bare fordi du har en segmenteringsfejl 410 00:34:42,290 --> 00:34:49,480 i en af ​​systemets funktioner, betyder typisk, at du netop ikke har kaldt det korrekt. 411 00:34:49,480 --> 00:34:52,440 Den hurtigste ting at gøre for at finde ud af, hvad der rent faktisk sker 412 00:34:52,440 --> 00:34:55,500 når du ser noget vanvittigt som dette, hver gang du ser en seg fejl, 413 00:34:55,500 --> 00:34:59,800 især hvis du har et program, der bruger mere end bare main, 414 00:34:59,800 --> 00:35:03,570 er at bruge en backtrace. 415 00:35:03,570 --> 00:35:13,080 I forkorte backtrace ved at skrive bt, i modsætning til den fulde backtrace ord. 416 00:35:13,080 --> 00:35:16,510 Men Charlotte, hvad der sker, når du skriver bt og tryk på Enter? 417 00:35:16,510 --> 00:35:23,200 [Charlotte] Det viser mig to linjer, linje 0 og linie 1. 418 00:35:23,200 --> 00:35:26,150 >> Yeah. Så linje 0 og linie 1. 419 00:35:26,150 --> 00:35:34,560 Det er de faktiske stakrammer, der var i øjeblikket i spil, når dit program styrtede ned. 420 00:35:34,560 --> 00:35:42,230 Begyndende fra den øverste ramme, ramme 0, og gå til den nederste, som er rammen 1. 421 00:35:42,230 --> 00:35:45,140 Vores øverste ramme er det strcmp ramme. 422 00:35:45,140 --> 00:35:50,080 Du kan tænke på det som svarer til det problem vi blot gør på quiz med pegepinde, 423 00:35:50,080 --> 00:35:54,890 hvor vi havde swap stakramme på toppen af ​​main stakramme, 424 00:35:54,890 --> 00:35:59,700 og vi havde de variabler, som swap brugte på toppen af ​​de variabler, main var bruger. 425 00:35:59,700 --> 00:36:08,440 Her vores styrt skete i vores strcmp funktion, der blev kaldt af vores vigtigste funktion, 426 00:36:08,440 --> 00:36:14,370 og backtrace giver os ikke kun de funktioner, som tingene mislykkedes, 427 00:36:14,370 --> 00:36:16,440 men det er også fortæller os, hvor alt blev kaldt fra. 428 00:36:16,440 --> 00:36:18,830 Så hvis jeg ruller over et lidt mere til højre, 429 00:36:18,830 --> 00:36:26,110 Vi kan se, at ja, vi var på linje 254 i denne strcmp-sse4.s fil. 430 00:36:26,110 --> 00:36:32,540 Men opkaldet blev foretaget ved buggy1.c, linie 6. 431 00:36:32,540 --> 00:36:35,960 Så det betyder, at vi kan gøre - er at vi bare kan gå tjekke ud og se, hvad der foregik 432 00:36:35,960 --> 00:36:39,930 ved buggy1.c, linie 6. 433 00:36:39,930 --> 00:36:43,780 Igen er der et par måder at gøre dette. Den ene er at afslutte ud af GDB 434 00:36:43,780 --> 00:36:49,460 eller få din kode åbner i et andet vindue og krydsreference. 435 00:36:49,460 --> 00:36:54,740 Det er i og for sig selv, er temmelig praktisk, fordi nu, hvis du er i kontortiden 436 00:36:54,740 --> 00:36:57,220 og du har fået en seg fejl og din TF er gad vide hvor alting var ved at bryde, 437 00:36:57,220 --> 00:36:59,710 kan du bare sige: "Åh, linje 6. Jeg ved ikke, hvad der foregår, 438 00:36:59,710 --> 00:37:03,670 men noget om linje 6 forårsager mit program til at bryde. " 439 00:37:03,670 --> 00:37:10,430 Den anden måde at gøre det er, kan du bruge denne kommando kaldet liste i GDB. 440 00:37:10,430 --> 00:37:13,650 Du kan også forkorte den med l.. 441 00:37:13,650 --> 00:37:18,910 Så hvis vi rammer l, hvad vi får her? 442 00:37:18,910 --> 00:37:21,160 Vi får en hel masse underlige ting. 443 00:37:21,160 --> 00:37:26,030 Dette er den faktiske samling kode 444 00:37:26,030 --> 00:37:29,860 der er i strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Det ser lidt funky, 446 00:37:32,440 --> 00:37:36,520 og grunden til at vi får det er fordi lige nu, 447 00:37:36,520 --> 00:37:40,160 GDB har os i ramme 0. 448 00:37:40,160 --> 00:37:43,070 >> Så når som helst vi ser på variabler, hver gang vi ser på kildekoden 449 00:37:43,070 --> 00:37:50,530 vi kigger på kildekoden, der relaterer til stakrammen vi er i øjeblikket i. 450 00:37:50,530 --> 00:37:53,200 Så for at få noget meningsfuldt, er vi nødt til 451 00:37:53,200 --> 00:37:57,070 flytte til en stak ramme, der giver mere mening. 452 00:37:57,070 --> 00:38:00,180 I dette tilfælde ville den vigtigste stakramme gøre lidt mere mening, 453 00:38:00,180 --> 00:38:02,680 fordi det var faktisk den kode, vi skrev. 454 00:38:02,680 --> 00:38:05,330 Ikke den strcmp kode. 455 00:38:05,330 --> 00:38:08,650 Den måde, du kan flytte mellem rammer, i dette tilfælde, fordi vi har to, 456 00:38:08,650 --> 00:38:10,430 Vi har 0 og 1, 457 00:38:10,430 --> 00:38:13,650 du gøre det med op-og ned-kommandoer. 458 00:38:13,650 --> 00:38:18,480 Hvis jeg flytter op én ramme, 459 00:38:18,480 --> 00:38:21,770 nu er jeg i den vigtigste stakramme. 460 00:38:21,770 --> 00:38:24,330 Jeg kan flytte ned for at gå tilbage til hvor jeg var, 461 00:38:24,330 --> 00:38:32,830 gå op igen, gå ned igen, og gå op igen. 462 00:38:32,830 --> 00:38:39,750 Hvis du nogensinde gøre dit program i GDB, du får et crash, får du backtrace, 463 00:38:39,750 --> 00:38:42,380 og du kan se, at det er i nogle fil, som du ikke ved, hvad der foregĺr. 464 00:38:42,380 --> 00:38:45,460 Du prøver liste, er koden ikke virke bekendt for dig, 465 00:38:45,460 --> 00:38:48,150 tage et kig på dine rammer og finde ud af hvor du er. 466 00:38:48,150 --> 00:38:51,010 Du er sandsynligvis i den forkerte stakramme. 467 00:38:51,010 --> 00:38:58,760 Eller i det mindste du er i en stak ramme, der er ikke en, som du virkelig kan debug. 468 00:38:58,760 --> 00:39:03,110 Nu, hvor vi er i den rette stakramme, vi er i main, 469 00:39:03,110 --> 00:39:08,100 nu kan vi bruge listen kommandoen til at regne ud, hvad linjen var. 470 00:39:08,100 --> 00:39:13,590 Og du kan se det, det udskrives det for os lige her. 471 00:39:13,590 --> 00:39:19,470 Men vi kan ramme en liste over alle de samme, og listen giver os denne nice udskrift 472 00:39:19,470 --> 00:39:23,920 af den faktiske kildekode, der foregår herinde. 473 00:39:23,920 --> 00:39:26,420 >> I særdeleshed kan vi se på linje 6. 474 00:39:26,420 --> 00:39:29,330 Vi kan se, hvad der foregår her. 475 00:39:29,330 --> 00:39:31,250 Og det ser ud til vi laver en streng sammenligning 476 00:39:31,250 --> 00:39:41,050 mellem strengen "CS50 rocks" og argv [1]. 477 00:39:41,050 --> 00:39:45,700 Noget om dette var ned. 478 00:39:45,700 --> 00:39:54,120 Så Missy, har du nogen tanker om, hvad der kunne ske her? 479 00:39:54,120 --> 00:39:59,400 [Missy] Jeg ved ikke, hvorfor det er ned. >> Du ved ikke, hvorfor det er ned? 480 00:39:59,400 --> 00:40:02,700 Jimmy, nogen tanker? 481 00:40:02,700 --> 00:40:06,240 [Jimmy] Jeg er ikke helt sikker, men sidste gang vi brugte streng sammenligne, 482 00:40:06,240 --> 00:40:10,260 eller strcmp, havde vi ligesom tre forskellige tilfælde under det. 483 00:40:10,260 --> 00:40:12,800 Vi havde ikke en ==, tror jeg ikke, ret i, at første linje. 484 00:40:12,800 --> 00:40:16,700 I stedet blev opdelt i tre, og én var == 0, 485 00:40:16,700 --> 00:40:19,910 den ene var <0, tror jeg, og én var> 0. 486 00:40:19,910 --> 00:40:22,590 Så måske noget i den retning? >> Yeah. Så der er dette problem 487 00:40:22,590 --> 00:40:27,200 af gør vi sammenligningen korrekt? 488 00:40:27,200 --> 00:40:31,660 Stella? Nogen tanker? 489 00:40:31,660 --> 00:40:38,110 [Stella] Jeg er ikke sikker. >> Ikke sikker. Daniel? Tanker? Okay. 490 00:40:38,110 --> 00:40:44,770 Det viser sig, hvad der sker lige her er, når vi kørte programmet 491 00:40:44,770 --> 00:40:48,370 og vi fik den seg fejl, da du kørte programmet for første gang, Daniel, 492 00:40:48,370 --> 00:40:50,800 gav du det nogen kommandolinjeargumenter? 493 00:40:50,800 --> 00:40:58,420 [Daniel] Nej >> Nej. I så fald, hvad er værdien af ​​argv [1]? 494 00:40:58,420 --> 00:41:00,920 >> Der er ingen værdi. >> Højre. 495 00:41:00,920 --> 00:41:06,120 Nå, der er nogen hensigtsmæssig streng værdi. 496 00:41:06,120 --> 00:41:10,780 Men der er en vis værdi. Hvad er den værdi, bliver gemt derinde? 497 00:41:10,780 --> 00:41:15,130 >> En skrald værdi? >> Det er enten en skraldespand værdi eller, i dette tilfælde, 498 00:41:15,130 --> 00:41:19,930 enden af ​​argv arrayet altid afsluttet med nul. 499 00:41:19,930 --> 00:41:26,050 Så hvad der rent faktisk fik gemt i der er null. 500 00:41:26,050 --> 00:41:30,810 Den anden måde at løse dette, snarere end at tænke det igennem, 501 00:41:30,810 --> 00:41:33,420 er at prøve at udskrive det. 502 00:41:33,420 --> 00:41:35,880 Det er her, jeg sagde, at bruge GDB er stor, 503 00:41:35,880 --> 00:41:40,640 fordi du kan printe ud alle de variabler, alle de værdier, du vil 504 00:41:40,640 --> 00:41:43,230 ved hjælp af denne handy-dandy p kommando. 505 00:41:43,230 --> 00:41:48,520 Så hvis jeg skriver p og derefter jeg skrive værdien af ​​en variabel eller navnet på en variabel, 506 00:41:48,520 --> 00:41:55,320 sige, argc, jeg kan se, at argc er 1. 507 00:41:55,320 --> 00:42:01,830 Hvis jeg ønsker at udskrive argv [0], kan jeg gøre det ligesom det. 508 00:42:01,830 --> 00:42:04,840 Og som vi så, argv [0] er altid navnet på dit program, 509 00:42:04,840 --> 00:42:06,910 altid navnet på den eksekverbare. 510 00:42:06,910 --> 00:42:09,740 Her kan du se det har fået den fulde sti navn. 511 00:42:09,740 --> 00:42:15,920 Jeg kan også printe ud argv [1] og se hvad der sker. 512 00:42:15,920 --> 00:42:20,890 >> Her fik vi denne slags mystiske værdi. 513 00:42:20,890 --> 00:42:23,890 Vi fik denne 0x0. 514 00:42:23,890 --> 00:42:27,850 Husk ved begyndelsen af ​​udtrykket, når vi talte om hexadecimale tal? 515 00:42:27,850 --> 00:42:34,680 Eller den lille spørgsmål i slutningen af ​​Pset 0 om, hvordan du repræsentere 50 i hex? 516 00:42:34,680 --> 00:42:39,410 Den måde, vi skriver hex numre i CS, bare for ikke at forvirre os selv 517 00:42:39,410 --> 00:42:46,080 med decimaltal, er vi altid præfiks dem med 0x. 518 00:42:46,080 --> 00:42:51,420 Så denne 0x altid betyder blot fortolke følgende nummer som et hexadecimalt tal, 519 00:42:51,420 --> 00:42:57,400 ikke som en streng, ikke som et decimaltal, som ikke er et binært tal. 520 00:42:57,400 --> 00:43:02,820 Da nummer 5-0 er et gyldigt tal i hexadecimal. 521 00:43:02,820 --> 00:43:06,240 Og det er et tal i decimal, 50. 522 00:43:06,240 --> 00:43:10,050 Så det er bare hvordan vi disambiguate. 523 00:43:10,050 --> 00:43:14,860 Så 0x0 midler hexadecimal 0, som også decimal 0, binære 0. 524 00:43:14,860 --> 00:43:17,030 Det er bare værdien 0. 525 00:43:17,030 --> 00:43:22,630 Det viser sig, at det er det nul er, faktisk, i hukommelsen. 526 00:43:22,630 --> 00:43:25,940 Null er blot 0. 527 00:43:25,940 --> 00:43:37,010 Her bestanddelen opbevaret ved argv [1] er nul. 528 00:43:37,010 --> 00:43:45,220 Så vi prøver at sammenligne vores "CS50 rocks" streng til en null-streng. 529 00:43:45,220 --> 00:43:48,130 Så dereferere null, forsøger at få adgang ting på null, 530 00:43:48,130 --> 00:43:55,050 de er typisk vil forårsage en slags segmentering fejl eller andre dårlige ting til at ske. 531 00:43:55,050 --> 00:43:59,350 Og det viser sig, at strcmp ikke kontrollerer at se 532 00:43:59,350 --> 00:44:04,340 uanset om du har bestået i en værdi, der er null. 533 00:44:04,340 --> 00:44:06,370 Snarere er det bare går fremad, forsøger at gøre sin ting, 534 00:44:06,370 --> 00:44:14,640 og hvis det seg fejl, det seg fejl, og det er dit problem. Du skal gå løse det. 535 00:44:14,640 --> 00:44:19,730 Virkelig hurtigt, hvordan kunne vi løse dette problem? Charlotte? 536 00:44:19,730 --> 00:44:23,540 [Charlotte] Du kan tjekke med hvis. 537 00:44:23,540 --> 00:44:32,240 Så hvis argv [1] er null, == 0, derefter returnere 1, eller noget [uforståeligt]. 538 00:44:32,240 --> 00:44:34,590 >> Yeah. Så det er en god måde at gøre det, som vi kan kontrollere at se, 539 00:44:34,590 --> 00:44:39,230 den værdi, vi er ved at passere ind strcmp, argv [1], er det null? 540 00:44:39,230 --> 00:44:45,830 Hvis det er null, så kan vi sige okay, afbryde. 541 00:44:45,830 --> 00:44:49,450 >> En mere almindelig måde at gøre dette på er at bruge den argc værdi. 542 00:44:49,450 --> 00:44:52,040 Du kan se lige her i starten af ​​main, 543 00:44:52,040 --> 00:44:58,040 vi udeladt den første test, som vi typisk gør, når vi bruger kommandolinjeargumenter, 544 00:44:58,040 --> 00:45:05,240 som er at teste, hvorvidt vores argc værdi er, hvad vi forventer. 545 00:45:05,240 --> 00:45:10,290 I dette tilfælde er vi forventer mindst to argumenter, 546 00:45:10,290 --> 00:45:13,660 navnet på programmet plus en anden. 547 00:45:13,660 --> 00:45:17,140 Fordi vi er ved at bruge det andet argument lige her. 548 00:45:17,140 --> 00:45:21,350 Så har en slags test på forhånd, før vores strcmp opkald 549 00:45:21,350 --> 00:45:37,390 at prøverne eller ej argv er mindst 2, vil også gøre det samme slags ting. 550 00:45:37,390 --> 00:45:40,620 Vi kan se, om det virker ved at køre programmet igen. 551 00:45:40,620 --> 00:45:45,610 Du kan altid genstarte din program inden GDB, som er virkelig rart. 552 00:45:45,610 --> 00:45:49,310 Du kan køre, og når du passerer på argumenter til dit program, 553 00:45:49,310 --> 00:45:53,060 du passerer dem i, når du ringer kører, ikke når du starter op GDB. 554 00:45:53,060 --> 00:45:57,120 På den måde kan du holde påberåbe dit program med forskellige argumenter hver gang. 555 00:45:57,120 --> 00:46:08,080 Så køre, eller igen, kan jeg skrive r, og lad os se hvad der sker, hvis vi skriver "hej". 556 00:46:08,080 --> 00:46:11,140 Det vil altid spørge dig, om du ønsker at starte det fra begyndelsen igen. 557 00:46:11,140 --> 00:46:17,490 Normalt vil du starte det fra begyndelsen igen. 558 00:46:17,490 --> 00:46:25,010 Og på dette punkt, det genstarter den igen, den udskriver 559 00:46:25,010 --> 00:46:28,920 det program, vi kører, buggy1, med det argument hej, 560 00:46:28,920 --> 00:46:32,720 og den udskriver denne standard ud, den siger, "Du får en D," trist ansigt. 561 00:46:32,720 --> 00:46:37,610 Men vi havde ikke seg fejl. Det siges, at processen afsluttet normalt. 562 00:46:37,610 --> 00:46:39,900 Så det ser godt ud. 563 00:46:39,900 --> 00:46:43,050 Ikke mere seg fejl, vi gjorde det forbi, 564 00:46:43,050 --> 00:46:48,190 så det ligner det faktisk var seg fejl bug, som vi fik. 565 00:46:48,190 --> 00:46:51,540 Desværre, det fortæller os, at vi får et D. 566 00:46:51,540 --> 00:46:54,090 >> Vi kan gå tilbage og se på koden og se, hvad der foregik der 567 00:46:54,090 --> 00:46:57,980 at finde ud af, hvad der var - hvorfor det fortalte os, at vi fik et D. 568 00:46:57,980 --> 00:47:03,690 Lad os se, her var det printf at sige, at du fik en D. 569 00:47:03,690 --> 00:47:08,540 Hvis vi skriver liste, som du holder skrive liste, det holder iteration ned gennem dit program, 570 00:47:08,540 --> 00:47:10,940 så det vil vise dig de første par linjer af dit program. 571 00:47:10,940 --> 00:47:15,450 Så det vil vise dig de næste par linjer, og den næste luns og den næste bid. 572 00:47:15,450 --> 00:47:18,240 Og det vil holde forsøger at gå ned. 573 00:47:18,240 --> 00:47:21,180 Og nu får vi at "Line nummer 16 er uden for rækkevidde." 574 00:47:21,180 --> 00:47:23,940 Fordi det kun har 15 linjer. 575 00:47:23,940 --> 00:47:30,310 Hvis du kommer til dette punkt, og din undrende, "Hvad skal jeg gøre?" kan du bruge kommandoen help. 576 00:47:30,310 --> 00:47:34,340 Brug hjælp og derefter give det navnet på en kommando. 577 00:47:34,340 --> 00:47:36,460 Og du kan se GDB giver os alle den slags ting. 578 00:47:36,460 --> 00:47:43,870 Det siger, "Med noget argument, opregner yderligere ti linjer efter eller omkring den tidligere fortegnelse. 579 00:47:43,870 --> 00:47:47,920 List - en liste over de ti linjer før - " 580 00:47:47,920 --> 00:47:52,960 Så lad os prøve at bruge liste minus. 581 00:47:52,960 --> 00:47:57,000 Og det viser de 10 linier tidligere, og du kan lege med liste en lille smule. 582 00:47:57,000 --> 00:48:02,330 Du kan gøre listen, liste - du kan endda give en liste over et nummer, ligesom liste 8, 583 00:48:02,330 --> 00:48:07,500 og det vil en liste over de 10 linier omkring linie 8. 584 00:48:07,500 --> 00:48:10,290 Og du kan se, hvad der foregår her, er at du har en enkel, hvis andet. 585 00:48:10,290 --> 00:48:13,980 Hvis du skriver i CS50 klipper, den udskriver "Du får et A." 586 00:48:13,980 --> 00:48:16,530 Ellers udskriver "Du får en D." 587 00:48:16,530 --> 00:48:23,770 Nedern by. Ok. Ja? 588 00:48:23,770 --> 00:48:26,730 >> [Daniel] Så når jeg forsøgte at gøre CS50 klipper uden anførselstegn, 589 00:48:26,730 --> 00:48:29,290 det siger "Du får en D." 590 00:48:29,290 --> 00:48:32,560 Jeg havde brug for citater for at få det til at virke, hvorfor så det? 591 00:48:32,560 --> 00:48:38,490 >> Yeah. Det viser sig, at når - det er en anden sjov lille tidbit - 592 00:48:38,490 --> 00:48:47,900 når du kører programmet, hvis vi kører det, og vi skriver i CS50 klipper, 593 00:48:47,900 --> 00:48:50,800 ligesom Daniel sagde han gjorde, og du trykker på Enter, 594 00:48:50,800 --> 00:48:52,870 det stadig siger vi får en D. 595 00:48:52,870 --> 00:48:55,580 Og spørgsmålet er, hvorfor er dette? 596 00:48:55,580 --> 00:49:02,120 Og det viser sig, at både vores terminal og GDB parse disse som to separate argumenter. 597 00:49:02,120 --> 00:49:04,800 For når der er en plads, der er underforstået som 598 00:49:04,800 --> 00:49:08,730 det første argument ophørt den næste argument er ved at begynde. 599 00:49:08,730 --> 00:49:13,260 Den måde at kombinere dem i to, eller ked af det, i ét argument, 600 00:49:13,260 --> 00:49:18,510 er at bruge citater. 601 00:49:18,510 --> 00:49:29,560 Så nu, hvis vi sætter det i anførselstegn og køre det igen, får vi et A. 602 00:49:29,560 --> 00:49:38,780 Så bare for at opsummere, ingen citater, CS50 og klipper parses som to separate argumenter. 603 00:49:38,780 --> 00:49:45,320 Med citater, er det parses som ét argument helt. 604 00:49:45,320 --> 00:49:53,070 >> Vi kan se dette med et breakpoint. 605 00:49:53,070 --> 00:49:54,920 Indtil videre har vi kørt vores program, og det er kørt 606 00:49:54,920 --> 00:49:58,230 indtil enten det seg fejl eller hits en fejl 607 00:49:58,230 --> 00:50:05,930 eller indtil det har forladt, og alle har været helt fint. 608 00:50:05,930 --> 00:50:08,360 Dette er ikke nødvendigvis den mest nyttige ting, fordi nogle gange 609 00:50:08,360 --> 00:50:11,840 du har en fejl i dit program, men det er ikke forårsager en segmentering fejl. 610 00:50:11,840 --> 00:50:16,950 Det er ikke forårsager din program til at stoppe eller sådan noget. 611 00:50:16,950 --> 00:50:20,730 Den måde at få GDB til pause dit program på et bestemt punkt 612 00:50:20,730 --> 00:50:23,260 er at sætte et breakpoint. 613 00:50:23,260 --> 00:50:26,520 Du kan enten gøre dette ved at sætte et breakpoint på et funktionsnavn 614 00:50:26,520 --> 00:50:30,770 eller du kan indstille en breakpoint på en bestemt linje kode. 615 00:50:30,770 --> 00:50:34,450 Jeg kan godt lide at sætte breakpoints på funktion navne, fordi - let at huske, 616 00:50:34,450 --> 00:50:37,700 og hvis du rent faktisk gå ind og ændre din kildekode op en lille smule, 617 00:50:37,700 --> 00:50:42,020 så vil din breakpoint vil faktisk bo på det samme sted i din kode. 618 00:50:42,020 --> 00:50:44,760 Hvorimod hvis du bruger linjenumre, og linjenumrene ændrer 619 00:50:44,760 --> 00:50:51,740 fordi du tilføjer eller sletter noget kode, så dine breakpoints er alle helt skruet op. 620 00:50:51,740 --> 00:50:58,590 En af de mest almindelige ting, jeg gør er sat en breakpoint på den primære funktion. 621 00:50:58,590 --> 00:51:05,300 Ofte vil jeg starte op GDB, vil jeg skrive b main, tryk på Enter, og der vil sætte en breakpoint 622 00:51:05,300 --> 00:51:10,630 på den vigtigste funktion, som bare siger, "pause i programmet, så snart du begynder at køre," 623 00:51:10,630 --> 00:51:17,960 og på den måde, når jeg kører mit program med, siger, CS50 klipper som to argumenter 624 00:51:17,960 --> 00:51:24,830 og tryk Enter, det bliver til hovedfunktionen, og det stopper lige ved den allerførste linje, 625 00:51:24,830 --> 00:51:30,620 lige før det vurderer den strcmp funktion. 626 00:51:30,620 --> 00:51:34,940 >> Da jeg er sat på pause, nu kan jeg begynde mucking rundt og se, hvad der foregår 627 00:51:34,940 --> 00:51:40,250 med alle de forskellige variabler, der er gået ind i mit program. 628 00:51:40,250 --> 00:51:43,670 Her kan jeg printe ud argc og se, hvad der foregår. 629 00:51:43,670 --> 00:51:50,030 Se, at argc er 3, fordi det har fået 3 forskellige værdier i det. 630 00:51:50,030 --> 00:51:54,060 Det har fået navnet på det program, har det fået det første argument, og det andet argument. 631 00:51:54,060 --> 00:52:09,330 Vi kan printe dem ud ved at kigge på argv [0], argv [1], og argv [2]. 632 00:52:09,330 --> 00:52:12,030 Så nu kan du også se, hvorfor dette strcmp opkald kommer til at mislykkes, 633 00:52:12,030 --> 00:52:21,650 fordi du kan se, at det gjorde opsplitte CS50 og klipperne i to separate argumenter. 634 00:52:21,650 --> 00:52:27,250 På dette punkt, når du har ramt et breakpoint kan du fortsætte med at springe gennem Deres program 635 00:52:27,250 --> 00:52:32,920 linje for linje, i modsætning til at starte programmet igen. 636 00:52:32,920 --> 00:52:35,520 Så hvis du ikke ønsker at starte programmet igen og bare fortsætte herfra, 637 00:52:35,520 --> 00:52:41,970 du kan bruge continue kommando og fortsætter vil køre programmet til ende. 638 00:52:41,970 --> 00:52:45,010 Ligesom det gjorde her. 639 00:52:45,010 --> 00:52:54,880 Men hvis jeg genstarte programmet, CS50 klipper, det rammer min breakpoint igen, 640 00:52:54,880 --> 00:52:59,670 og denne gang, hvis jeg ikke ønsker at bare gå hele vejen gennem resten af ​​programmet, 641 00:52:59,670 --> 00:53:08,040 Jeg kan bruge den næste kommando, som jeg også forkorte med n. 642 00:53:08,040 --> 00:53:12,960 Og det vil gå gennem programmet linje for linje. 643 00:53:12,960 --> 00:53:17,530 Så du kan se som tingene udføre, som variable forandring, som tingene bliver opdateret. 644 00:53:17,530 --> 00:53:21,550 Hvilket er temmelig nice. 645 00:53:21,550 --> 00:53:26,570 Den anden cool ting er stedet for at gentage den samme kommando igen og igen og igen, 646 00:53:26,570 --> 00:53:30,670 hvis du bare trykke Enter - så her kan du se, jeg har ikke skrevet i noget - 647 00:53:30,670 --> 00:53:33,780 hvis jeg bare trykke Enter, vil det gentage den forrige kommando, 648 00:53:33,780 --> 00:53:36,900 eller den forrige GDB kommando, som jeg lige har lagt i. 649 00:53:36,900 --> 00:53:56,000 Jeg kan holde trykke Enter og det vil holde trinvist gennem min kode linje for linje. 650 00:53:56,000 --> 00:53:59,310 Jeg vil opfordre jer til at gå tjekke de andre buggy programmer også. 651 00:53:59,310 --> 00:54:01,330 Vi har ikke tid til at komme igennem dem alle i dag i snit. 652 00:54:01,330 --> 00:54:05,890 Kildekoden er der, så du kan slags se, hvad der foregår 653 00:54:05,890 --> 00:54:07,730 bag kulisserne, hvis du virkelig sidder fast, 654 00:54:07,730 --> 00:54:11,940 men i det mindste, øve bare starter op GDB, 655 00:54:11,940 --> 00:54:13,940 køre programmet indtil den bryder på dig, 656 00:54:13,940 --> 00:54:18,260 få backtrace, finde ud af hvad fungere flystyrtet var i, 657 00:54:18,260 --> 00:54:24,450 hvilken linje det var på, udskrivning ud nogle variable værdier, 658 00:54:24,450 --> 00:54:30,140 bare så du får en fornemmelse for det, fordi der virkelig vil hjælpe dig fremover. 659 00:54:30,140 --> 00:54:36,340 På dette tidspunkt vil vi holde op ud af GDB, som du bruger afslutte eller bare q. 660 00:54:36,340 --> 00:54:40,460 Hvis dit program er midt i at køre endnu, og det har ikke forladt, 661 00:54:40,460 --> 00:54:43,510 det vil altid spørge dig, "Er du sikker på at du virkelig ønsker at holde op?" 662 00:54:43,510 --> 00:54:48,770 Du kan bare trykke ja. 663 00:54:48,770 --> 00:54:55,250 >> Nu vil vi se på det næste problem, vi har, som er katten program. 664 00:54:55,250 --> 00:54:59,880 Hvis du ser kort på omdirigere og rør, vil du se, at Tommy bruger dette program 665 00:54:59,880 --> 00:55:07,540 der dybest set udskriver alle resultater af en fil til skærmen. 666 00:55:07,540 --> 00:55:12,660 Så hvis jeg løber kat, det er faktisk en indbygget program til apparatet, 667 00:55:12,660 --> 00:55:16,860 og hvis du har Mac-computere, du kan gøre dette på din Mac også, hvis du åbner terminal. 668 00:55:16,860 --> 00:55:25,630 Og vi - kat, lad os sige, cp.c, og tryk på Enter. 669 00:55:25,630 --> 00:55:29,640 Hvad dette gjorde, hvis vi rulle op en lille smule og se, hvor vi kørte linjen, 670 00:55:29,640 --> 00:55:40,440 eller hvor vi kørte katten kommando, det bogstavelig talt lige udskrives indholdet af cp.c til vores skærm. 671 00:55:40,440 --> 00:55:44,140 Vi kan køre det igen, og du kan sætte i flere filer sammen. 672 00:55:44,140 --> 00:55:49,880 Så du kan gøre katten cp.c, og så kan vi også sammenkæde den cat.c fil, 673 00:55:49,880 --> 00:55:53,250 som er det program, vi er ved at skrive, 674 00:55:53,250 --> 00:55:58,140 og det vil udskrive begge filer tilbage til tilbage til vores skærm. 675 00:55:58,140 --> 00:56:05,490 Så hvis vi rulle op en lille smule, kan vi se, at når vi kørte denne kat cp.c, cat.c, 676 00:56:05,490 --> 00:56:17,110 Først udskrives den cp-filen, og derefter under det, printet det ud den cat.c fil lige hernede. 677 00:56:17,110 --> 00:56:19,650 Vi vil bruge dette til bare få vores våde fødder. 678 00:56:19,650 --> 00:56:25,930 Leg med almindelig udskrivning til terminalen, se, hvordan det virker. 679 00:56:25,930 --> 00:56:39,170 Hvis du fyre åbner med gedit cat.c, tryk Enter, 680 00:56:39,170 --> 00:56:43,760 du kan se det program, vi er ved at skrive. 681 00:56:43,760 --> 00:56:48,980 Vi har medtaget denne nice kedel plade, så vi ikke behøver at bruge tid på at skrive alt det ud. 682 00:56:48,980 --> 00:56:52,310 Vi tjekker også antallet af argumenter gik i. 683 00:56:52,310 --> 00:56:56,910 Vi udskriver en dejlig brugsmeddelelse. 684 00:56:56,910 --> 00:57:00,950 >> Det er den slags ting, der, igen, ligesom vi har talt om, 685 00:57:00,950 --> 00:57:04,490 det er næsten ligesom muskel hukommelse. 686 00:57:04,490 --> 00:57:07,190 Bare husk at holde gør det samme slags ting 687 00:57:07,190 --> 00:57:11,310 og altid udskrive en slags nyttige besked 688 00:57:11,310 --> 00:57:17,670 , så folk ved, hvordan du kører dit program. 689 00:57:17,670 --> 00:57:21,630 Med kat, er det ret simpelt, vi bare kommer til at gå igennem alle de forskellige argumenter 690 00:57:21,630 --> 00:57:24,300 der blev overført til vores program, og vi vil udskrive 691 00:57:24,300 --> 00:57:29,950 deres indhold ud til skærmen en ad gangen. 692 00:57:29,950 --> 00:57:35,670 For at udskrive filer ud til skærmen, vi kommer til at gøre noget meget lignende 693 00:57:35,670 --> 00:57:38,120 til, hvad vi gjorde i slutningen af ​​quizzen. 694 00:57:38,120 --> 00:57:45,350 I slutningen af ​​quizzen, der ansætter program, måtte vi åbne op for en fil, 695 00:57:45,350 --> 00:57:48,490 og derefter havde vi at udskrive til den. 696 00:57:48,490 --> 00:57:54,660 I dette tilfælde vil vi åbne en fil, og vi vil læse fra det i stedet. 697 00:57:54,660 --> 00:58:00,630 Så vi kommer til at udskrive, i stedet for til en fil, vi kommer til at udskrive til skærmen. 698 00:58:00,630 --> 00:58:05,830 Så udskriver til skærmen, du har alle gjort før med printf. 699 00:58:05,830 --> 00:58:08,290 Så det er ikke vanvittigt. 700 00:58:08,290 --> 00:58:12,190 Men læser en fil er lidt underligt. 701 00:58:12,190 --> 00:58:17,300 Vi vil gå igennem det en lille smule ad gangen. 702 00:58:17,300 --> 00:58:20,560 Hvis du fyre gå tilbage til det sidste problem på din quiz, problem 33, 703 00:58:20,560 --> 00:58:27,280 den første linje, at vi vil gøre her, at åbne filen, er meget lig hvad vi gjorde der. 704 00:58:27,280 --> 00:58:36,370 Så Stella, hvad betyder denne linje se ud, når vi åbner en fil? 705 00:58:36,370 --> 00:58:47,510 [Stella] Capital FIL *, fil - >> Okay. >> - Er lig med fopen. >> Yup. 706 00:58:47,510 --> 00:58:55,980 Som i dette tilfælde er? Det er i kommentaren. 707 00:58:55,980 --> 00:59:06,930 >> Det er i kommentaren? argv [i] og r? 708 00:59:06,930 --> 00:59:11,300 >> Præcis. Lige på. Så Stella er helt rigtigt. 709 00:59:11,300 --> 00:59:13,720 Dette er, hvad den linje ser ud. 710 00:59:13,720 --> 00:59:19,670 Vi kommer til at få en fil stream variabel, skal det opbevares i en fil *, så alle caps, 711 00:59:19,670 --> 00:59:25,720 FILE, *, og navnet på denne variabel vil være fil. 712 00:59:25,720 --> 00:59:32,250 Vi kunne kalde det hvad vi vil. Vi kunne kalde det first_file, eller file_i, hvad vi gerne vil. 713 00:59:32,250 --> 00:59:37,590 Og derefter navnet på filen blev vedtaget i på kommandolinjen til dette program. 714 00:59:37,590 --> 00:59:44,450 Så det er gemt i argv [i,] og derefter vil vi åbne denne fil i læse mode. 715 00:59:44,450 --> 00:59:48,100 Nu da vi har åbnet filen, hvad er de ting, vi altid skal huske at gøre 716 00:59:48,100 --> 00:59:52,230 når vi har åbnet en fil? Luk den. 717 00:59:52,230 --> 00:59:57,220 Så Missy, hvordan vi lukker en fil? 718 00:59:57,220 --> 01:00:01,020 [Missy] fclose (fil) >> fclose (fil). Præcis. 719 01:00:01,020 --> 01:00:05,340 Great. Okay. Hvis vi ser på dette at gøre kommentar lige her, 720 01:00:05,340 --> 01:00:11,940 den siger, "Open argv [i] og udskrive dens indhold til stdout." 721 01:00:11,940 --> 01:00:15,460 >> Standard ud er et underligt navn. Stdout er bare vores måde at sige 722 01:00:15,460 --> 01:00:22,880 vi ønsker at printe det til terminalen, vi ønsker at printe det til standard output stream. 723 01:00:22,880 --> 01:00:26,450 Vi kan faktisk slippe af med denne kommentar lige her. 724 01:00:26,450 --> 01:00:36,480 Jeg har tænkt mig at kopiere og indsætte det, da det er, hvad vi gjorde. 725 01:00:36,480 --> 01:00:41,290 På dette tidspunkt, har vi nu til at læse filen lidt efter lidt. 726 01:00:41,290 --> 01:00:46,300 Vi har diskuteret et par måder at læse filer. 727 01:00:46,300 --> 01:00:51,830 Hvilke af dem er din favorit indtil videre? 728 01:00:51,830 --> 01:00:57,960 Hvilke måder har du set eller kan du huske, at læse filer? 729 01:00:57,960 --> 01:01:04,870 [Daniel] fread? >> Fread? Så fread er én. Jimmy, kender du nogen andre? 730 01:01:04,870 --> 01:01:12,150 [Jimmy] Nej >> Okay. Nope. Charlotte? Alexander? Eventuelle andre? Okay. 731 01:01:12,150 --> 01:01:20,740 Så de andre er fgetc, er en, som vi vil bruge en masse. 732 01:01:20,740 --> 01:01:26,410 Der er også fscanf, du fyre se et mønster her? 733 01:01:26,410 --> 01:01:29,170 De har alle begynder med f. Noget at gøre med en fil. 734 01:01:29,170 --> 01:01:35,260 Der er fread, fgetc, fscanf. Disse er alle de læsning funktioner. 735 01:01:35,260 --> 01:01:49,120 For at skrive vi har fwrite, har vi fputc stedet for fgetc. 736 01:01:49,120 --> 01:01:58,250 Vi har også fprintf gerne vi så på quizzen. 737 01:01:58,250 --> 01:02:01,680 Da dette er et problem, der involverer læsning fra en fil, 738 01:02:01,680 --> 01:02:04,940 vi kommer til at bruge en af ​​disse tre funktioner. 739 01:02:04,940 --> 01:02:10,890 Vi kommer ikke til at bruge disse funktioner hernede. 740 01:02:10,890 --> 01:02:14,880 Disse funktioner er alle fundet i standard I / O-bibliotek. 741 01:02:14,880 --> 01:02:17,510 Så hvis man ser på toppen af ​​dette program, 742 01:02:17,510 --> 01:02:24,110 du kan se, at vi allerede har inkluderet header filen for standard I / O-bibliotek. 743 01:02:24,110 --> 01:02:27,120 Hvis vi ønsker at finde ud af hvilken en vi vil bruge, 744 01:02:27,120 --> 01:02:29,690 Vi kan altid åbne man-siderne. 745 01:02:29,690 --> 01:02:34,350 Så vi kan skrive mand stdio 746 01:02:34,350 --> 01:02:43,180 og læs alt om stdio input-og output-funktioner i C. 747 01:02:43,180 --> 01:02:49,870 Og vi kan allerede se oh, se. Det nævne fgetc, det nævne fputc. 748 01:02:49,870 --> 01:02:57,220 Så du kan bore ned lidt og se på, siger, fgetc 749 01:02:57,220 --> 01:03:00,060 og se på sin mand siden. 750 01:03:00,060 --> 01:03:03,430 Du kan se, at det går sammen med en hel masse andre funktioner: 751 01:03:03,430 --> 01:03:12,640 fgetc, fgets, getc, getchar, får, ungetc, og dens input af tegn og strygere. 752 01:03:12,640 --> 01:03:19,180 Så det er sådan vi læser i tegn og strygere fra filer fra standard input, 753 01:03:19,180 --> 01:03:21,990 som i det væsentlige fra brugeren. 754 01:03:21,990 --> 01:03:24,780 Og det er, hvordan vi gør det i virkeligheden C. 755 01:03:24,780 --> 01:03:30,850 Så dette er ikke bruger GetString og getchar funktioner 756 01:03:30,850 --> 01:03:36,840 at vi anvendt fra CS50 biblioteket. 757 01:03:36,840 --> 01:03:39,710 Vi vil gøre dette problem i et par forskellige måder 758 01:03:39,710 --> 01:03:43,430 så du kan se to forskellige måder at gøre det. 759 01:03:43,430 --> 01:03:48,490 Både fread funktion, Daniel nævnt og fgetc er gode måder at gøre det. 760 01:03:48,490 --> 01:03:53,790 Jeg tror fgetc er lidt nemmere, fordi det kun har, som du ser, 761 01:03:53,790 --> 01:03:59,660 et argument, det FILE *, at vi forsøger at læse karakter fra, 762 01:03:59,660 --> 01:04:02,740 og dens returværdi er en int. 763 01:04:02,740 --> 01:04:05,610 Og det er lidt forvirrende, ikke? 764 01:04:05,610 --> 01:04:11,450 >> Fordi vi får en karakter, så hvorfor ikke dette afkast en char? 765 01:04:11,450 --> 01:04:18,700 I gutter har nogen ideer om, hvorfor dette måske ikke returnere en char? 766 01:04:18,700 --> 01:04:25,510 [Missy svar, uforståelig] >> Yeah. Så Missy er helt rigtigt. 767 01:04:25,510 --> 01:04:31,570 Hvis det er ASCII, så er denne heltal kan kortlægges til en faktisk char. 768 01:04:31,570 --> 01:04:33,520 Kunne være et ASCII-tegn, og det er rigtigt. 769 01:04:33,520 --> 01:04:36,220 Det er præcis, hvad der sker. 770 01:04:36,220 --> 01:04:39,190 Vi bruger en int, blot fordi den har flere bits. 771 01:04:39,190 --> 01:04:44,750 Det er større end en char, vores char kun har 8 bit, at 1 byte på vores 32-bit maskiner. 772 01:04:44,750 --> 01:04:48,520 Og en int har alle 4 bytes 'værd af plads. 773 01:04:48,520 --> 01:04:50,940 Og det viser sig, at den måde fgetc virker, 774 01:04:50,940 --> 01:04:53,940 hvis vi rulle ned i vores synopsis i denne mand side en lille smule, 775 01:04:53,940 --> 01:05:05,000 rulle hele vejen ned. Det viser sig, at de bruger denne særlige værdi kaldet EOF. 776 01:05:05,000 --> 01:05:09,640 Det er en speciel konstant som returværdien af ​​fgetc funktion 777 01:05:09,640 --> 01:05:14,570 hver gang du rammer slutningen af ​​filen, eller hvis du får en fejl. 778 01:05:14,570 --> 01:05:18,170 Og det viser sig, at for at gøre disse sammenligninger med EOF ordentligt, 779 01:05:18,170 --> 01:05:24,060 du vil have den ekstra mængde information, du har i en int 780 01:05:24,060 --> 01:05:28,420 i modsætning til anvendelse af en char variabel. 781 01:05:28,420 --> 01:05:32,130 Selvom fgetc effektivt at få en karakter fra en fil, 782 01:05:32,130 --> 01:05:38,450 du ønsker at huske, at det er på vej tilbage noget, der er af typen int til dig. 783 01:05:38,450 --> 01:05:41,360 Når det er sagt, er det forholdsvis let at bruge. 784 01:05:41,360 --> 01:05:44,960 Det kommer til at give os en karakter, så alle vi skal gøre, er at spørge filen, 785 01:05:44,960 --> 01:05:48,440 "Giv mig det næste tegn, giv mig det næste tegn, giv mig det næste tegn," 786 01:05:48,440 --> 01:05:51,400 indtil vi kommer til slutningen af ​​filen. 787 01:05:51,400 --> 01:05:54,730 Og det vil trække i ét tegn ad gangen fra vores fil, 788 01:05:54,730 --> 01:05:56,250 og så kan vi gøre, hvad vi vil med det. 789 01:05:56,250 --> 01:06:00,160 Vi kan gemme det, kan vi tilføje det til en streng, vi kan printe det ud. 790 01:06:00,160 --> 01:06:04,630 Gør noget af det. 791 01:06:04,630 --> 01:06:09,600 >> Zoome ud igen og går tilbage til vores cat.c program, 792 01:06:09,600 --> 01:06:16,170 hvis vi skal bruge fgetc, 793 01:06:16,170 --> 01:06:21,710 hvordan kan vi gribe dette næste linje kode? 794 01:06:21,710 --> 01:06:26,020 Vi kommer til at bruge - fread vil gøre noget lidt anderledes. 795 01:06:26,020 --> 01:06:32,600 Og denne gang, vil vi bare bruge fgetc til at få et tegn ad gangen. 796 01:06:32,600 --> 01:06:40,910 For at behandle en hel fil, hvad kan vi så gøre? 797 01:06:40,910 --> 01:06:44,030 Hvor mange karakterer er der i en fil? 798 01:06:44,030 --> 01:06:47,390 Der er mange. Så har du sandsynligvis ønsker at få en 799 01:06:47,390 --> 01:06:49,860 og derefter få en anden og få en anden og få en anden. 800 01:06:49,860 --> 01:06:53,330 Hvilken slags algoritme tror du, vi måske nødt til at bruge her? 801 01:06:53,330 --> 01:06:55,470 Hvilken type -? [Alexander] En for-løkke? >> Præcis. 802 01:06:55,470 --> 01:06:57,500 En form for loop. 803 01:06:57,500 --> 01:07:03,380 En for-løkke er faktisk stor, i dette tilfælde. 804 01:07:03,380 --> 01:07:08,620 Og som du sagde, det lyder som om du vil have en sløjfe over hele filen, 805 01:07:08,620 --> 01:07:11,820 få et tegn ad gangen. 806 01:07:11,820 --> 01:07:13,850 Eventuelle forslag til, hvad der kunne ligne? 807 01:07:13,850 --> 01:07:22,090 [Alexander, uforståelig] 808 01:07:22,090 --> 01:07:30,050 >> Okay, bare fortælle mig på engelsk hvad du prøver at gøre? [Alexander, uforståelig] 809 01:07:30,050 --> 01:07:36,270 Så i dette tilfælde, lyder det som om vi bare forsøger at sløjfe over hele filen. 810 01:07:36,270 --> 01:07:45,330 [Alexander] Så jeg > Størrelsen af ​​-? 811 01:07:45,330 --> 01:07:49,290 Jeg gætte størrelsen af ​​filen, ikke? Størrelsen - we'll bare skrive det sådan her. 812 01:07:49,290 --> 01:07:57,470 Størrelse på filen for tiden, i + +. 813 01:07:57,470 --> 01:08:04,610 Så det viser sig, at den måde, du gør dette ved hjælp af fgetc, og dette er nyt, 814 01:08:04,610 --> 01:08:10,460 er, at der ikke er nogen nem måde at bare få størrelsen på en fil 815 01:08:10,460 --> 01:08:16,979 med denne "sizeof" type konstruere, at du har set før. 816 01:08:16,979 --> 01:08:20,910 Når vi bruger det fgetc funktion, introducerer vi en slags 817 01:08:20,910 --> 01:08:29,069 nye, funky syntaks til dette for-løkke, hvor der i stedet for at bruge bare en grundlæggende tæller 818 01:08:29,069 --> 01:08:33,920 at gå tegn for tegn, vi kommer til at trække et tegn ad gangen, 819 01:08:33,920 --> 01:08:37,120 et tegn ad gangen, og den måde, vi ved, vi er i slutningen 820 01:08:37,120 --> 01:08:41,290 ikke, når vi har talt et bestemt antal tegn, 821 01:08:41,290 --> 01:08:49,939 men når den karakter vi trække sig ud, er, at speciel slutning på fil karakter. 822 01:08:49,939 --> 01:08:58,689 Så vi kan gøre dette ved - jeg kalder denne lm, og vi vil initialisere det 823 01:08:58,689 --> 01:09:08,050 med vores første opkald for at få det første tegn ud af filen. 824 01:09:08,050 --> 01:09:14,979 Så denne del lige her, vil dette få en karakter ud af filen 825 01:09:14,979 --> 01:09:20,840 og gemme den i den variable lm. 826 01:09:20,840 --> 01:09:25,420 Vi kommer til at holde gøre dette, indtil vi kommer til slutningen af ​​filen, 827 01:09:25,420 --> 01:09:41,170 som vi gør ved at teste for den karakter ikke er lig med, at særlige EOF karakter. 828 01:09:41,170 --> 01:09:48,750 Og så i stedet for at gøre lm + +, ville der blot øge værdien, 829 01:09:48,750 --> 01:09:52,710 så hvis vi læser en A ud af filen, en kapital A, siger, 830 01:09:52,710 --> 01:09:56,810 ch + + ville give os b, og så vi ville få c og derefter d. 831 01:09:56,810 --> 01:09:59,310 Det er tydeligvis ikke, hvad vi ønsker. Hvad vi ønsker her 832 01:09:59,310 --> 01:10:05,830 i denne sidste bit er vi ønsker at få det næste tegn fra filen. 833 01:10:05,830 --> 01:10:09,500 >> Så hvordan kan vi få det næste tegn fra filen? 834 01:10:09,500 --> 01:10:13,470 Hvordan får vi det første tegn fra filen? 835 01:10:13,470 --> 01:10:17,200 [Student] fgetfile? >> Fgetc, eller, undskyld, du var helt rigtigt. 836 01:10:17,200 --> 01:10:20,470 Jeg stavede det lige der. Så yeah. 837 01:10:20,470 --> 01:10:26,240 Her stedet for at gøre lm + +, 838 01:10:26,240 --> 01:10:29,560 vi bare vil kalde fgetc (fil) igen 839 01:10:29,560 --> 01:10:39,180 og gemme resultatet i vores samme lm variabel. 840 01:10:39,180 --> 01:10:43,730 [Student spørgsmål, uforståelig] 841 01:10:43,730 --> 01:10:52,390 >> Dette er, hvor disse fil * fyre er speciel. 842 01:10:52,390 --> 01:10:59,070 Den måde, de arbejder, er de - når du først åbne - når du først gør, at fopen opkald, 843 01:10:59,070 --> 01:11:04,260 FILE * reelt fungerer som en pegepind til begyndelsen af ​​filen. 844 01:11:04,260 --> 01:11:12,830 Og så hver gang du ringer fgetc, flyttes et tegn gennem filen. 845 01:11:12,830 --> 01:11:23,280 Så når du kalder det, er du inkrementering filpointeren med ét tegn. 846 01:11:23,280 --> 01:11:26,210 Og når du fgetc igen, er du flytter det en anden karakter 847 01:11:26,210 --> 01:11:28,910 og en anden karakter og anden karakter og et andet tegn. 848 01:11:28,910 --> 01:11:32,030 [Student spørgsmål, uforståelig] >> And that's - yeah. 849 01:11:32,030 --> 01:11:34,810 Det er lidt af denne magi under kølerhjelmen. 850 01:11:34,810 --> 01:11:37,930 Du skal bare holde forøgelsen igennem. 851 01:11:37,930 --> 01:11:46,510 På dette tidspunkt, er du i stand til rent faktisk at arbejde med en karakter. 852 01:11:46,510 --> 01:11:52,150 Så hvordan kan vi udskrive denne ud til skærmen, nu? 853 01:11:52,150 --> 01:11:58,340 Vi kan bruge den samme printf ting, som vi brugte før. 854 01:11:58,340 --> 01:12:00,330 At vi har brugt al semester. 855 01:12:00,330 --> 01:12:05,450 Vi kan kalde printf, 856 01:12:05,450 --> 01:12:21,300 og vi kan passere i karakter ligesom det. 857 01:12:21,300 --> 01:12:27,430 En anden måde at gøre det er snarere end at bruge printf og at skulle gøre dette format streng, 858 01:12:27,430 --> 01:12:29,490 Vi kan også bruge en af ​​de andre funktioner. 859 01:12:29,490 --> 01:12:40,090 Vi kan bruge fputc, som udskriver et tegn til skærmen, 860 01:12:40,090 --> 01:12:52,580 undtagen hvis vi ser på fputc - lad mig zoome ud en lille smule. 861 01:12:52,580 --> 01:12:56,430 Vi ser, hvad der er rart er det tager i det tegn, vi læser ved hjælp fgetc, 862 01:12:56,430 --> 01:13:05,100 men så er vi nødt til at give det en strøm til at udskrive til. 863 01:13:05,100 --> 01:13:11,850 Vi kan også bruge putchar funktion, som vil sætte direkte til standard ud. 864 01:13:11,850 --> 01:13:16,070 Så der er en hel masse forskellige muligheder, som vi kan bruge til udskrivning. 865 01:13:16,070 --> 01:13:19,580 De er alle i standard I / O-bibliotek. 866 01:13:19,580 --> 01:13:25,150 Når du vil udskrive - så printf, som standard, vil udskrive til den særlige standard ud stream, 867 01:13:25,150 --> 01:13:27,910 nemlig at stdout. 868 01:13:27,910 --> 01:13:41,300 Så vi kan bare henvise til det som en slags denne magiske værdi, stdout herinde. 869 01:13:41,300 --> 01:13:48,410 Ups. Sæt semikolon udenfor. 870 01:13:48,410 --> 01:13:52,790 >> Dette er en masse nye, funky information herinde. 871 01:13:52,790 --> 01:13:58,600 Meget af dette er meget idiomatisk, i den forstand at det er kode 872 01:13:58,600 --> 01:14:05,700 der er skrevet på denne måde, bare fordi det er ren at læse, let at læse. 873 01:14:05,700 --> 01:14:11,520 Der er mange forskellige måder at gøre det, mange forskellige funktioner, du kan bruge, 874 01:14:11,520 --> 01:14:14,680 men vi har en tendens til blot følge de samme mønstre igen og igen. 875 01:14:14,680 --> 01:14:20,180 Så du skal ikke blive overrasket, hvis du ser kode som denne kommer op igen og igen. 876 01:14:20,180 --> 01:14:25,690 Ok. På dette tidspunkt er vi nødt til at bryde for dagen. 877 01:14:25,690 --> 01:14:31,300 Tak for at komme. Tak for at se, hvis du er online. Og vi vil se dig næste uge. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]