[Powered by Google Translate] [CS50 Raamatukogu] [Nate Hardison] [Harvardi Ülikool] [See on CS50. CS50.TV] CS50 raamatukogu on kasulik vahend, et meil on paigaldatud seade sisse et oleks lihtsam kirjutada programme, mis nõuab kasutajatel sisend. Selles videos, me tõmmake kardin ja vaatame, mida täpselt on CS50 raamatukogu. In video C raamatukogud, me räägime kuidas sa # include päised faili raamatukogu oma lähtekoodi, ja siis siduda binaarse teegi faili ajal ühendab etapp koostamise protsessi. Päisefaile täpsustada liides raamatukogu. See tähendab, et nad üksikasjalikult kõiki vahendeid, et raamatukogus on olemas, kus saab kasutada, nagu funktsioon deklaratsioonid, konstandid ja andmetüüpe. Binaarne raamatukogu fail sisaldab rakendamise raamatukogu, mis on koostatud raamatukogu päisefaile ja raamatukogu. c lähtekoodi failid. Binaarne raamatukogu fail ei ole väga huvitav vaadata, sest see on, noh, binaarne. Niisiis, oletame, kui heita pilk päisefaile raamatukogu asemel. Sel juhul on ainult üks header fail nimega cs50.h. Oleme paigaldatud see kasutaja sisaldavad kataloog koos teiste süsteemi raamatukogude päisefaile. Üks esimesi asju märkad on see, et cs50.h # sisaldab päisefaile teistest raamatukogudest - float, piirid, standard bool ja standard lib. Jällegi põhimõtet järgides ei jalgratta leiutamist, oleme loonud CS0 raamatukogu kasutades vahendeid, mida teised meile andnud. Järgmine asi, mida te näete on raamatukogu, mis me defineerime uue tüübi nimega "string." See liin on tõesti lihtsalt loob alias char * tüüpi, nii et see ei võluväel immutama uus string tüüpi atribuute tavaliselt seotud string objektid teistes keeltes, nagu pikkus. Põhjus, miks me seda teinud on kaitsta uus programmeerijad Verine üksikasjad osuti kuni nad on valmis. Järgmise osa päisefail on deklaratsiooni funktsioonid et CS50 raamatukogu pakub koos dokumentidega. Teade detailsus kommentaarid siia. See on super oluline, et inimesed teaksid, kuidas kasutada neid funktsioone. Me kuulutame, mis omakorda toimib ajendab kasutaja ja tagastamise tähemärki, kahekohalised, ujukite, ints, kaua igatseb, ja stringid, kasutades oma stringi tüüpi. Järgides põhimõtet tiedonpiilotus, oleme pannud meie määratlus eraldi. c rakendamise fail - cs50.c-- asub kasutaja allikas kataloog. Oleme lisanud selle faili nii, et saate seda vaadata, õppima, ja kompileeri see erinevate masinatega, kui soovite, kuigi me arvame, et see on parem töötada seadet selles klassis. Igatahes, võtame pilk see nüüd. Funktsioonid getchar, GetDouble, GetFloat, GetInt ja GetLongLong kõik ehitatud peal getString funktsioon. Selgub, et nad kõik järgivad sisuliselt sama muster. Nad kasutavad samas silmus ajendab kasutaja jaoks üks rida sisend. Nad naasta eriline väärtus, kui kasutaja sisendite tühi rida. Nad püüavad sõeluda kasutaja sisendit sobivat tüüpi, olgu see char, double, float, jne Ja siis nad kas naasta tulemus, kui sisend on edukalt sõeluda või nad reprompt kasutaja. Kõrgel tasemel, ei ole midagi tõesti keeruline siin. Te olete kirjutanud sarnaselt struktureeritud koodi ise minevikus. Võib-olla kõige segasena suunatud osa on sscanf kõne, et korrastab kasutaja sisendit. Sscanf on osa sisend formaadi konverteerimise pere. Ta elab standard io.h ja tema ülesanne on sõeluda C string, vastavalt kindlas vormingus, säilitades sõeluda tulemusi muutuja sätestatud helistaja. Kuna sisendvorming muutmise funktsioonid on väga kasulik, laialdaselt kasutatavad funktsioonid mis ei ole super intuitiivne alguses, läheme üle, kuidas sscanf töötab. Esimene argument sscanf on char * - kursor sümboli. Sest funktsioon korralikult töötada, et märk peaks olema esimene märk C string, lõpetatakse null \ 0 märk. See on string sõeluda Teine argument sscanf on stringi, tavaliselt möödus nagu string konstantne, ja sa võisid näha stringi nagu seda enne, kui kasutate printf. Protsendimärk vormingus stringi näitab teisenduse. Märgi kohe pärast protsendimärk, näitab C tüüpi, et me tahame sscanf teisendada. Aastal GetInt, näed, et seal on% d ja% c. See tähendab, et sscanf püüan koma int -% d - ja char -% c. Iga teisenduse stringi, sscanf loodab vastav argument hiljem oma väidet nimekirja. See argument tuleb viidata nõuetekohaselt trükitud asukoht , kuhu salvestada konverteerimise tulemuse. Tüüpiline viis seda teha on luua muutuja serva enne sscanf kõne iga kirje, mida soovite sõeluda alates string ja siis kasuta aadress operaator - märk - läbida viiteid nende muutujate sscanf kõne. Näete, et GetInt me seda täpselt. Vahetult enne sscanf kõne, me kuulutame int nimetatakse n ja char kõne c kohta virna, ja võtame viiteid need sscanf kõne. Haara need muutujad korstnat eelistatakse kasutada ruumi eraldatud edasi hunnik koos malloc, sest teil vältida õhuliini malloc kõne ja sa ei pea muretsema lekib mälu. Tegelased ei prefiksiga protsenti märk ei küsi vahetamisega. Pigem nad lihtsalt lisada formaadi kirjeldus. Näiteks kui formaat string GetInt olid% d asemel, sscanf näeks ette täht, millele järgneb int, ja kuigi see oleks üritada muuta int, see ei tee midagi muud. Ainus erand on see tühik. Valge ruum tähemärki stringi suvalise summa tühik - isegi üldse mitte. Nii, et miks kommentaar mainib olla juhtivate ja / või trailing tühik. Niisiis, siinkohal tundub meie sscanf kõne püüab sõeluda kasutaja sisend string kontrollides võimalik juhtiv tühik, järgneb int et konverteeritakse ja salvestatakse int muutuja n järgneb mingi summa tühik, millele järgneb märk salvestatud char muutujat c. Aga tagastatav väärtus? Sscanf on sõeluda sisendrida algusest lõpuni, peatudes lõpuks või kui märk sisend ei sobi formaadis iseloomu või kui ta ei saa teha vahetamisega. See on tagastatav väärtus kasutatakse eristada, kui ta katkestas. Kui ta lõpetas, sest see on jõudnud sisend string enne mis tahes ümberehitused ja enne ta ei sobi osa stringi, siis erilist pidev EOF tagastatakse. Vastasel korral tagastab arvu edukaid tulemusi, mis võiks olla 0, 1 või 2, sest me oleme palunud kaks konversioone. Meie puhul me tahame veenduda, et kasutaja sisestatud int ja ainult int. Niisiis, me tahame sscanf naasta 1. Vaata miks? Kui sscanf tagastatakse 0, siis ei ole ümberarvestus tehti, nii kasutaja sisestatud midagi muud kui int alguses sisend. Kui sscanf tagastab 2, siis kasutaja ei korralikult kirjuta see alguses sisend, kuid nad siis kirjutada mõnes mitte-tühimärk hiljem alates% c konverteerimine õnnestunud. Vau, see on päris pikk selgitus üks funktsioon kõne. Igatahes, kui soovite rohkem teavet sscanf ja tema õed-vennad, vaadake man-lehekülgi, Google, või mõlemad. Seal on palju vormingustringile võimalusi, ja need võib säästa palju füüsilist tööd, kui nad püüavad sõeluda stringid C. Lõplik funktsioon raamatukogu pilk on getString. Selgub, et getString on keeruline ülesanne kirjutada õigesti, kuigi tundub selline lihtne, ühine ülesanne. Miks on see nii? Noh, mõtleme, kuidas me kavatseme hoida joont, et kasutaja tipib sisse Kuna string on jada sümbolid, me võiksite seda säilitada massiivi kohta virna, kuid meil oleks vaja teada, kui kaua massiivi saab olema, kui me kuulutada. Samuti siis, kui me tahame panna see hunnik, me peame läbima, et malloc baitide arvu tahame reservi, kuid see on võimatu. Meil pole aimugi, kui palju tähemärki kasutaja sisestada enne kui kasutaja tegelikult ei kirjuta. Naiivne lahendus sellele probleemile on lihtsalt endale suure tüki ruumi, ütleme, plokk 1000 tähemärki kasutaja sisend, eeldades, et kasutaja oleks kunagi sisestada string, mis pikk. See on halb idee kahel põhjusel. Esiteks, eeldades, et kasutajad tavaliselt ei kirjuta stringe, mis pikk, võid jäätmete palju mälu. On kaasaegsete masinatega, see ei pruugi olla probleem, kui sa seda teed ühes või kahes üksikjuhtumid, aga kui te võtate kasutaja sisend tsüklina ja hoidmine hilisemaks kasutamiseks, saate kiiresti imege ton mälu. Lisaks, kui programm olete kirjalikult on väiksem arvuti - seade nagu nutitelefon või midagi muud piiratud mälu - see lahendus toob kaasa probleeme palju kiiremini. Teine, veel tõsine põhjus seda teha on see, et ta jätab oma programmi haavatav sellele, mida nimetatakse buffer overflow rünnak. Programmeerimise, puhver on mälu, mida kasutatakse ajutiselt talletada väljundseisundi andmed, mis antud juhul on meie 1000-char blokeerida. Buffer overflow tekib siis andmed kirjutatakse juba lõppenud blokeerida. Näiteks, kui kasutaja tegelikult ei kirjuta enam kui 1000 tähemärki. Te olete kogenud seda kogemata kavandamisel massiivid. Kui teil on massiiv 10. ints, miski ei takista sind üritab lugeda ega kirjutada 15. int. Puuduvad kompilaator hoiatused või vigu. Programm lihtsalt vigu otse edasi ja pöördub mälu kus ta arvab, 15. int saab olema, ja seda saab kirjutada oma muudest muutujatest. Halvimal juhul võid kirjutada mõned oma programmi sisene kontrollimehhanismid, põhjustades oma programmi tegelikult täita erinevaid juhiseid kui soovite. Nüüd, see ei ole ühine teha seda kogemata, kuid see on üsna levinud meetod, mis halvad poisid kasutavad murda programmid ja pane pahatahtliku koodi teiste inimeste arvuteid. Seetõttu me ei saa lihtsalt kasutada meie naiivne lahendus. Meil on vaja ära hoida meie programmid on vähem kaitstud et buffer overflow rünnak. Selleks peame tagama, et meie puhver võib kasvada, kui loeme rohkem kasutajalt. Lahendus? Me kasutame hunnik eraldatud puhver. Kuna me suurust saab muuta, kasutades resize RealLOC funktsioon, ja me jälgida kahte numbrit - indeksi kõrval tühi pesa puhver ja pikkus või maht puhver. Me loeme tähemärki kasutaja ükshaaval kasutades fgetc funktsioon. Argument fgetc funktsioon võtab - stdin - on standardkõvera sisend string, mis on preconnected sisendkanal, mida kasutatakse üle kasutaja sisend terminalist programm. Kui kasutaja liigid uus tegelane, meil vaadata, kui indeks järgmise vaba pesa pluss 1 on suurem kui võimsus puhver. 1 jõuab, sest kui järgmine vaba indeks on 5, siis meie puhver on pikkus peab olema 6 tänud kuni 0 indekseerimist. Kui me oleme ruum otsa puhvris, siis üritame suurust muuta, kahekordistades seda nii, et me kärpima mitu korda, et me resize kui kasutaja on kirjutades tõesti pikk jada. Kui string on saanud liiga pikk või kui me otsa hunnik mälu, me vabastada oma puhver ja tagastab null. Lõpuks lisab char puhver. Kui kasutaja tabamust siseneda või naasta, signalisatsiooni uus liin, või eriline char - kontrolli d - mis signaale lõpuks sisend, meil vaadata, kui kasutaja tegelikult sisestatud üldse midagi. Kui ei, siis tagastab null. Vastasel sest meie puhver on tõenäoliselt suurem kui vajame, halvimal juhul on peaaegu kaks korda nii suur kui vaja kuna me kahekordistub iga kord, kui me suurust, teeme uue koopia string kasutades lihtsalt palju ruumi, et me vajame. Lisame pildi 1 malloc kõne nii et seal on ruumi eriline null terminaator iseloomu - \ 0, mis me lisab stringi kui me kopeerige ülejäänud tegelased, kasutades strncpy asemel strcpy nii et saame määrata täpselt, kui palju tähemärki me soovite kopeerida. Strcpy kopeerib kuni see tabab \ 0. Siis me vabastada oma puhver ja tagastab eksemplari helistaja. Kes teadis sellise lihtsa-näilisest funktsiooni saab nii keeruline? Nüüd sa tead, mida läheb CS50 raamatukogu. Minu nimi on Nate Hardison, ja see on CS50. [CS50.TV]