1 00:00:00,000 --> 00:00:02,490 [Powered by Google Translate] [CS50 Бібліятэка] 2 00:00:02,490 --> 00:00:04,220 [Nate Хардисон] [Harvard University] 3 00:00:04,220 --> 00:00:07,260 [Гэта CS50. CS50.TV] 4 00:00:07,260 --> 00:00:11,510 Бібліятэка CS50 з'яўляецца карысным інструментам, які мы ўсталявалі на прыладу 5 00:00:11,510 --> 00:00:15,870 каб зрабіць яго прасцей для вас, каб напісаць праграму, якая прапануе карыстачу для ўводу. 6 00:00:15,870 --> 00:00:21,670 У гэтым відэа мы будзем цягнуць заслону і паглядзім, што менавіта знаходзіцца ў CS50 бібліятэкі. 7 00:00:21,670 --> 00:00:25,520 >> У відэа на бібліятэкі C, мы гаворым пра тое, як вы # ўключыць загалоўкі файлаў 8 00:00:25,520 --> 00:00:27,570 бібліятэкі ў зыходны код, 9 00:00:27,570 --> 00:00:31,150 а затым вы звязваеце з двайковага файла бібліятэкі ў стадыі кампаноўкі 10 00:00:31,150 --> 00:00:33,140 з працэсу кампіляцыі. 11 00:00:33,140 --> 00:00:36,440 У загалоўку файла паказваецца інтэрфейс бібліятэкі. 12 00:00:36,440 --> 00:00:41,280 Гэта значыць, яны падрабязна ўсе рэсурсы, што ў бібліятэцы даступныя для выкарыстання, 13 00:00:41,280 --> 00:00:45,250 як функцыя дэкларацый, канстанты і тыпы дадзеных. 14 00:00:45,250 --> 00:00:48,890 Двайковы файл бібліятэкі ўтрымлівае рэалізацыю бібліятэкі, 15 00:00:48,890 --> 00:00:54,580 які складаецца з загалоўка бібліятэкі, файлы і бібліятэкі. з файламі зыходнага кода. 16 00:00:54,580 --> 00:00:59,820 >> Двайковага файла бібліятэкі не вельмі цікава паглядзець на, так як гэта, ну, у двайковай сістэме. 17 00:00:59,820 --> 00:01:03,300 Такім чынам, давайце зірнем на файлы загалоўкаў для бібліятэкі замест гэтага. 18 00:01:03,300 --> 00:01:07,710 У гэтым выпадку ёсць толькі адзін загаловак файла з імем cs50.h. 19 00:01:07,710 --> 00:01:11,040 Мы ўсталявалі яго ў карыстацкі каталог ўключае 20 00:01:11,040 --> 00:01:15,150 разам з файламі іншых бібліятэк сістэмы загалоўку. 21 00:01:15,150 --> 00:01:21,530 >> Адна з першых рэчаў, якія вы заўважыце, што cs50.h # ўключае ў сябе загалоўкавыя файлы з іншых бібліятэк - 22 00:01:21,530 --> 00:01:25,670 паплаўка, абмежаванні, стандартныя лагічны, і стандартныя LIB. 23 00:01:25,670 --> 00:01:28,800 Зноў жа, кіруючыся прынцыпам не вынаходзіць кола, 24 00:01:28,800 --> 00:01:33,490 мы пабудавалі CS0 бібліятэкі з дапамогай інструментаў, якія іншыя прадастаўлена для нас. 25 00:01:33,490 --> 00:01:38,690 >> Наступная рэч, якую вы ўбачыце ў бібліятэцы з'яўляецца тое, што мы вызначаем новы тып, званы «струны». 26 00:01:38,690 --> 00:01:42,330 Гэтая лінія сапраўды толькі стварае псеўданім для знакавых тыпу *, 27 00:01:42,330 --> 00:01:46,000 так што гэта не можа магічным чынам надаць новы тып радкі з атрыбутамі 28 00:01:46,000 --> 00:01:49,650 звычайна звязаныя з радковых аб'ектаў на іншых мовах, 29 00:01:49,650 --> 00:01:50,850 такіх як даўжыня. 30 00:01:50,850 --> 00:01:55,180 Таму мы зрабілі гэта, каб засцерагчы новых праграмістаў крывавыя падрабязнасці 31 00:01:55,180 --> 00:01:57,580 паказальнікаў, пакуль яны не гатовыя. 32 00:01:57,580 --> 00:02:00,130 >> Наступная частка загалоўка файла дэкларацыі функцый 33 00:02:00,130 --> 00:02:04,410 CS50, што бібліятэка падае разам з дакументацыяй. 34 00:02:04,410 --> 00:02:06,940 Звярніце ўвагу на ўзровень дэталізацыі ў каментарах тут. 35 00:02:06,940 --> 00:02:10,560 Гэта супер важна, каб людзі ведалі, як выкарыстоўваць гэтыя функцыі. 36 00:02:10,560 --> 00:02:19,150 Мы заяўляем, у сваю чаргу, функцыямі, каб заахвоціць карыстальнікаў і вяртання знакаў, двухмесныя, паплаўкі, цэлымі, 37 00:02:19,150 --> 00:02:24,160 даўно марыць, і радкі, выкарыстоўваючы наш уласны тып радка. 38 00:02:24,160 --> 00:02:26,260 Кіруючыся прынцыпам ўтойвання інфармацыі, 39 00:02:26,260 --> 00:02:31,640 мы паставілі нашым вызначэннем ў асобным файле рэалізацыі з -. cs50.c-- 40 00:02:31,640 --> 00:02:35,110 размешчаны ў каталогу крыніца карыстальнік. 41 00:02:35,110 --> 00:02:38,040 Мы пры ўмове, што файл, так што вы можаце зірнуць на яе, 42 00:02:38,040 --> 00:02:41,490 даведацца ад яго, і перакампіляваць яго на розных машынах, калі вы хочаце, 43 00:02:41,490 --> 00:02:45,510 нават калі мы думаем, што лепш працаваць на прыборы для гэтага класа. 44 00:02:45,510 --> 00:02:47,580 У любым выпадку, давайце паглядзім на гэта цяпер. 45 00:02:49,020 --> 00:02:54,620 >> Функцыі GetChar, GetDouble, GetFloat, GetInt, і GetLongLong 46 00:02:54,620 --> 00:02:58,160 Усё пабудавана на вяршыні GetString функцыі. 47 00:02:58,160 --> 00:03:01,510 Аказваецца, што ўсе яны ідуць па сутнасці той жа схеме. 48 00:03:01,510 --> 00:03:04,870 Яны выкарыстоўваюць той час як цыкл, каб заахвоціць карыстальнікаў для адной радком ўводу. 49 00:03:04,870 --> 00:03:08,430 Яны вяртаюць адмысловае значэнне, калі карыстальнік ўводзіць пустую радок. 50 00:03:08,430 --> 00:03:11,750 Яны спрабуюць разабраць ўваходу карыстача ў якасці адпаведнага тыпу, 51 00:03:11,750 --> 00:03:15,010 няхай гэта будзе сімвал, двайныя, з якая плавае кропкай, і г.д. 52 00:03:15,010 --> 00:03:18,710 І тады яны альбо вяртаюць вынік, калі ўваход быў паспяхова завершаны 53 00:03:18,710 --> 00:03:21,330 або яны reprompt карыстальнік. 54 00:03:21,330 --> 00:03:24,230 >> На высокім узроўні, няма нічога сапраўды складана тут. 55 00:03:24,230 --> 00:03:28,760 Вы маглі б напісаць так жа структураваны код сабе ў мінулым. 56 00:03:28,760 --> 00:03:34,720 Мабыць, самы загадкавы выгляд часткі Sscanf выклік, які аналізуе уведзеныя карыстачом дадзеныя. 57 00:03:34,720 --> 00:03:38,160 Sscanf з'яўляецца часткай пераўтварэння сям'і фармат ўводу. 58 00:03:38,160 --> 00:03:42,300 Ён жыве ў io.h стандарт, і яго праца складаецца ў разабраць радок C, 59 00:03:42,300 --> 00:03:46,520 ў адпаведнасці з вызначаным фарматам, захоўвання разбору вынікаў у зменную 60 00:03:46,520 --> 00:03:48,720 якія прадстаўляюцца абаненту. 61 00:03:48,720 --> 00:03:53,570 Паколькі ўваходны функцыі пераўтварэння фармату вельмі карысна, шырока выкарыстоўваюцца функцыі 62 00:03:53,570 --> 00:03:56,160 , Якія не з'яўляюцца супер інтуітыўна спачатку, 63 00:03:56,160 --> 00:03:58,300 мы пойдзем над тым, як Sscanf працуе. 64 00:03:58,300 --> 00:04:03,330 >> Першы аргумент Sscanf гэта сімвал * - паказальнік на знак. 65 00:04:03,330 --> 00:04:05,150 Для таго каб функцыя працавала правільна, 66 00:04:05,150 --> 00:04:08,340 , Што знак павінен быць першым знакам радкі C, 67 00:04:08,340 --> 00:04:12,270 спыняецца з нулявым \ 0 характару. 68 00:04:12,270 --> 00:04:15,120 Гэта радок для разбору 69 00:04:15,120 --> 00:04:18,269 Другі аргумент Sscanf гэта фармат радкі, 70 00:04:18,269 --> 00:04:20,839 звычайна перадаецца ў выглядзе радка пастаяннай, 71 00:04:20,839 --> 00:04:24,040 і вы маглі бачыць радок, як гэта раней пры выкарыстанні Printf. 72 00:04:24,040 --> 00:04:28,650 Знак адсотка ў радку фармату паказвае на спецификатор пераўтварэнні. 73 00:04:28,650 --> 00:04:30,850 Характар ​​адразу пасля знака адсотка, 74 00:04:30,850 --> 00:04:35,430 паказвае на тып C, які мы хочам Sscanf пераўтварэнні. 75 00:04:35,430 --> 00:04:40,090 У GetInt, вы бачыце, што ёсць д% і% аб. 76 00:04:40,090 --> 00:04:48,690 Гэта азначае, што Sscanf пастараемся дзесятковай INT -% D - і сімвал -% с. 77 00:04:48,690 --> 00:04:51,510 Для кожнага спецификатор пераўтварэнні ў фармат радкі, 78 00:04:51,510 --> 00:04:56,620 Sscanf чакае, што адпаведны аргумент пазней у сваім спісе аргументаў. 79 00:04:56,620 --> 00:05:00,850 Гэты аргумент павінен паказваць на месцазнаходжанне належным тыпізаваных 80 00:05:00,850 --> 00:05:04,000 , У якім захоўваецца вынік пераўтварэнні. 81 00:05:04,000 --> 00:05:08,910 >> Тыповы спосаб зрабіць гэта складаецца ў стварэнні зменнай у стэку перад выклікам Sscanf 82 00:05:08,910 --> 00:05:11,440 Для кожнага элемента, які вы хочаце, каб разабраць з радка 83 00:05:11,440 --> 00:05:15,520 , А затым выкарыстоўваць аператар адрасы - амперсанда - перадаць паказальнікі 84 00:05:15,520 --> 00:05:19,100 у гэтых зменных на заклік Sscanf. 85 00:05:19,100 --> 00:05:22,720 Вы можаце бачыць, што ў GetInt мы робім менавіта гэта. 86 00:05:22,720 --> 00:05:28,240 Прама перад выкліку Sscanf, мы заяўляем Int называецца п і сімвал з выкліку ў стэку, 87 00:05:28,240 --> 00:05:32,340 і мы пераходзім паказальнікі на іх у выкліку Sscanf. 88 00:05:32,340 --> 00:05:35,800 Падстаўляючы гэтыя зменныя ў стэку з'яўляецца пераважным ў параўнанні з выкарыстаннем прасторы, вылучанага 89 00:05:35,800 --> 00:05:39,350 ў кучы з таНос, так як дазваляе пазбегнуць накладных выдаткаў на таНос выкліку, 90 00:05:39,350 --> 00:05:43,060 і вам не прыйдзецца турбавацца аб уцечцы памяці. 91 00:05:43,060 --> 00:05:47,280 Персанажы не папярэднічаецца знакам адсотка ня падкажыце пераўтварэнні. 92 00:05:47,280 --> 00:05:50,380 Хутчэй яны проста дадаць у спецыфікацыі фармату. 93 00:05:50,380 --> 00:05:56,500 >> Напрыклад, калі ў радку фармату ў GetInt былі% D замест гэтага, 94 00:05:56,500 --> 00:05:59,800 Sscanf будзе шукаць літары ідуць INT, 95 00:05:59,800 --> 00:06:04,360 і пакуль ён будзе спрабаваць пераўтварыць Int, ён не будзе рабіць нічога іншага с. 96 00:06:04,360 --> 00:06:07,440 Адзінае выключэнне з гэтага прабелу. 97 00:06:07,440 --> 00:06:11,030 Прабелы ў радку фармату адпавядае любую колькасць прабелаў - 98 00:06:11,030 --> 00:06:12,890 нават няма ўвогуле. 99 00:06:12,890 --> 00:06:18,100 Такім чынам, вось чаму каментара згадвае, магчыма, з вядучымі і / або канчатковых прабелаў. 100 00:06:18,100 --> 00:06:22,910 Такім чынам, на дадзены момант гэта выглядае як выклік нашым Sscanf пастараемся разабраць радкі ўводу карыстальнікам 101 00:06:22,910 --> 00:06:25,380 , Правяраючы магчымыя вядучыя прабелы, 102 00:06:25,380 --> 00:06:29,300 варта Int, які будзе канвертаваны і захаваны ў Int зменнай п 103 00:06:29,300 --> 00:06:33,090 варта некаторы колькасць прабелаў, і варта сімвал 104 00:06:33,090 --> 00:06:35,810 захоўвацца ў сімвал зменнай с. 105 00:06:35,810 --> 00:06:37,790 >> Што аб вяртанні значэнне? 106 00:06:37,790 --> 00:06:41,560 Sscanf будзе аналізаваць ўваходныя лініі ад пачатку да канца, 107 00:06:41,560 --> 00:06:44,860 прыпынку, калі яна дасягае канца або калі персанаж ва ўваходны 108 00:06:44,860 --> 00:06:49,320 не адпавядае фармату характар ​​або калі ён не можа зрабіць пераўтварэнні. 109 00:06:49,320 --> 00:06:52,690 Прыйшоў вяртання выкарыстоўваецца вылучыць, калі ён спыніўся. 110 00:06:52,690 --> 00:06:55,670 Калі ён спыніўся, таму што ён дасягнуў канца ўваходных радкі 111 00:06:55,670 --> 00:07:00,630 Перад выкананнем любых пераўтварэнняў і перад адмовай у адпаведнасці з часткай радкі фармату, 112 00:07:00,630 --> 00:07:04,840 Затым спецыяльная канстанта EOF вяртаецца. 113 00:07:04,840 --> 00:07:08,200 У адваротным выпадку яна вяртае колькасць паспяховых пераходаў, 114 00:07:08,200 --> 00:07:14,380 які можа быць 0, 1, або 2, так як мы папрасілі 2 пераўтварэнні. 115 00:07:14,380 --> 00:07:19,000 У нашым выпадку, мы хочам пераканацца, што карыстач увёў у Int і толькі Int. 116 00:07:19,000 --> 00:07:23,370 >> Такім чынам, мы хочам, каб вярнуцца Sscanf 1. Даведайцеся, чаму? 117 00:07:23,370 --> 00:07:26,850 Калі Sscanf вярнула 0, то пераўтварэнне не былі зробленыя, 118 00:07:26,850 --> 00:07:31,690 так што карыстальнік увёў нешта іншае, чым Int ў пачатку ўваходзе. 119 00:07:31,690 --> 00:07:37,100 Калі Sscanf вяртае 2, то карыстач не правільна ўвесці яго ў пачатку ўводу, 120 00:07:37,100 --> 00:07:41,390 але затым яны ўвялі ў некаторых не-знаку пасля 121 00:07:41,390 --> 00:07:44,940 з% з паспяховасць пераўтварэнні. 122 00:07:44,940 --> 00:07:49,570 Нічога сабе, гэта даволі шырокае тлумачэнне для аднаго выкліку функцыі. 123 00:07:49,570 --> 00:07:53,460 У любым выпадку, калі вы хочаце больш інфармацыі аб Sscanf і яго браты і сёстры, 124 00:07:53,460 --> 00:07:57,130 праверыць мужчыну старонкі, Google, або абодвух. 125 00:07:57,130 --> 00:07:58,780 Ёсць шмат варыянтаў фармату радкі, 126 00:07:58,780 --> 00:08:03,830 і яны могуць захаваць вам шмат ручной працы пры спробе разабраць радкі ў C. 127 00:08:03,830 --> 00:08:07,180 >> Апошняя функцыя ў бібліятэцы глядзець на гэта GetString. 128 00:08:07,180 --> 00:08:10,310 Аказваецца, што GetString з'яўляецца складанай функцыяй, каб напісаць правільна, 129 00:08:10,310 --> 00:08:14,290 нават калі яна здаецца такі просты, агульная задача. 130 00:08:14,290 --> 00:08:16,170 Чаму гэта так? 131 00:08:16,170 --> 00:08:21,380 Ну, давайце падумаем пра тое, як мы збіраемся захоўваць радок, карыстач уводзіць цалі 132 00:08:21,380 --> 00:08:23,880 Так як радок ўяўляе сабой паслядоўнасць знакаў, 133 00:08:23,880 --> 00:08:26,430 мы маглі б захоўваць яго ў масіў у стэку, 134 00:08:26,430 --> 00:08:31,250 але мы павінны ведаць, як доўга масіва будзе, калі мы аб'явім яго. 135 00:08:31,250 --> 00:08:34,030 Сапраўды гэтак жа, калі мы хочам, каб пакласці яго на кучу, 136 00:08:34,030 --> 00:08:38,090 мы павінны перайсці да таНос колькасць байт, мы хочам рэзерву, 137 00:08:38,090 --> 00:08:39,730 Але гэта немагчыма. 138 00:08:39,730 --> 00:08:42,760 Мы паняцця не маем, колькі знакаў карыстальнік будзе ўводзіць 139 00:08:42,760 --> 00:08:46,590 перш чым карыстальнік на самай справе іх набору. 140 00:08:46,590 --> 00:08:50,720 >> Наіўнае рашэнне гэтай праблемы, гэта проста пакідаем за сабой вялікі кавалак прасторы, скажам, 141 00:08:50,720 --> 00:08:54,540 Блок з 1000 знакаў для ўводу карыстальніка, 142 00:08:54,540 --> 00:08:57,980 пры ўмове, што карыстач ніколі б не ўвесці ў радок, якая доўга. 143 00:08:57,980 --> 00:09:00,810 Гэта дрэнная ідэя па дзвюх прычынах. 144 00:09:00,810 --> 00:09:05,280 Па-першае, мяркуецца, што карыстачы звычайна не ўводзіце ў радку так доўга, 145 00:09:05,280 --> 00:09:07,610 Вы маглі б марнаваць шмат памяці. 146 00:09:07,610 --> 00:09:10,530 На сучасных машынах, гэта не можа быць праблемай, калі вы робіце гэта 147 00:09:10,530 --> 00:09:13,890 ў адным або двух асобных выпадках, 148 00:09:13,890 --> 00:09:17,630 Але калі вы прымаеце ўваходзе карыстальніка ў пятлю і захоўванню для наступнага выкарыстання, 149 00:09:17,630 --> 00:09:20,870 Вы можаце хутка паглынаць тоны памяці. 150 00:09:20,870 --> 00:09:24,450 Акрамя таго, калі праграма, якую вы пішаце для меншага кампутара - 151 00:09:24,450 --> 00:09:28,100 прылады, напрыклад, смартфона ці нешта іншае з абмежаваным аб'ёмам памяці - 152 00:09:28,100 --> 00:09:32,060 гэта рашэнне можа выклікаць праблемы значна хутчэй. 153 00:09:32,060 --> 00:09:36,450 Другая, больш сур'ёзная прычына, каб не рабіць гэтага ў тым, што ён пакідае вашу праграму ўразлівай 154 00:09:36,450 --> 00:09:39,710 тое, што называецца атака перапаўнення буфера. 155 00:09:39,710 --> 00:09:45,840 У праграмаванні, буфер памяці, які выкарыстоўваецца для часовага захоўвання ўваходных або выходных дадзеных, 156 00:09:45,840 --> 00:09:48,980 які ў дадзеным выпадку з'яўляецца наш 1000-сімвалаў блокаў. 157 00:09:48,980 --> 00:09:53,370 Перапаўненне буфера адбываецца, калі дадзеныя запісваюцца ў канцы мінулага блок. 158 00:09:53,370 --> 00:09:57,790 >> Напрыклад, калі карыстач на самай справе тыпу ў больш чым 1000 сімвалаў. 159 00:09:57,790 --> 00:10:01,570 Вы, магчыма, выпрабавалі гэта выпадкова пры праграмаванні з масівамі. 160 00:10:01,570 --> 00:10:05,620 Калі ў вас ёсць масіў з 10 цэлых лікаў, нішто не перашкаджае вам спрабую чытаць, ні пісаць 161 00:10:05,620 --> 00:10:07,810 15 Int. 162 00:10:07,810 --> 00:10:10,000 Ёсць ніякіх папярэджанняў кампілятара або памылкі. 163 00:10:10,000 --> 00:10:13,250 Праграма проста прамашкі наперад і звяртаецца да памяці 164 00:10:13,250 --> 00:10:18,150 дзе яна думае, што 15-Int будзе, і гэта можа перазапісаць іншыя зменныя. 165 00:10:18,150 --> 00:10:22,040 У горшым выпадку, вы можаце перазапісаць некаторыя ўнутраныя вашай праграмы 166 00:10:22,040 --> 00:10:26,820 механізмы кантролю, у выніку чаго ваша праграма на самай справе выконваць розныя інструкцыі 167 00:10:26,820 --> 00:10:28,340 чым вы разлічвалі. 168 00:10:28,340 --> 00:10:31,360 >> Дык вось, гэта не з'яўляецца агульным для гэтага выпадкова, 169 00:10:31,360 --> 00:10:35,150 Але гэта даволі распаўсюджаная тэхніка, дрэнныя хлопцы выкарыстоўваць, каб разбіць праграм 170 00:10:35,150 --> 00:10:39,080 і пакласці шкоднаснага кода на кампутары іншых людзей. 171 00:10:39,080 --> 00:10:42,910 Такім чынам, мы не можам проста выкарыстоўваць нашы наіўныя рашэння. 172 00:10:42,910 --> 00:10:45,590 Нам трэба знайсці спосаб, каб нашы праграмы з уразлівымі 173 00:10:45,590 --> 00:10:47,880 да атакі перапаўнення буфера. 174 00:10:47,880 --> 00:10:51,430 Каб зрабіць гэта, мы павінны пераканацца, што нашы буфера можа расці, як мы чытаем 175 00:10:51,430 --> 00:10:53,850 больш ўваходных дадзеных ад карыстальніка. 176 00:10:53,850 --> 00:10:57,440 Рашэнне? Мы выкарыстоўваем буфера кучы вылучаецца. 177 00:10:57,440 --> 00:10:59,950 Так як мы можам змяніць яго памер дапамогі змены памеру пераразмеркаваць функцыі, 178 00:10:59,950 --> 00:11:04,580 і мы адсочваем два лікі - індэкс наступнай пусты слот ў буферы 179 00:11:04,580 --> 00:11:08,390 і даўжыню або ёмістасць буфера. 180 00:11:08,390 --> 00:11:13,210 Мы чытаем у знакі ад карыстальнікаў па адным выкарыстаннем fgetc функцыі. 181 00:11:13,210 --> 00:11:19,360 Аргумент fgetc функцыя прымае - стандартны ўвод - гэта спасылка на стандартную радок уводу, 182 00:11:19,360 --> 00:11:23,810 якая з'яўляецца злучальнікі ўваходнага канала, які выкарыстоўваецца для перадачы карыстацкага ўводу 183 00:11:23,810 --> 00:11:26,270 ад тэрмінала да праграме. 184 00:11:26,270 --> 00:11:29,890 >> Кожны раз, калі карыстальнік ўводзіць новага персанажа, мы правяраем, калі індэкс 185 00:11:29,890 --> 00:11:35,810 на наступны свабодны слот плюс 1 больш, чым ёмістасць буфера. 186 00:11:35,810 --> 00:11:39,690 1 Прыходзіць, таму што калі наступны свабодны індэкс роўны 5, 187 00:11:39,690 --> 00:11:44,150 Затым даўжыню наш буфер павінен быць 6 Дзякуй 0, індэксацыя. 188 00:11:44,150 --> 00:11:48,350 Калі мы не хапіць месца ў буферы, то мы спрабуем змяніць яе памер, 189 00:11:48,350 --> 00:11:51,690 падваенне яго так, што мы скарацілі колькасць разоў, што мы змяняны 190 00:11:51,690 --> 00:11:54,760 калі карыстач друкуе ў вельмі доўгую радок. 191 00:11:54,760 --> 00:11:57,950 Калі радок стаў занадта доўгім або калі мы запусцім з кучы памяці, 192 00:11:57,950 --> 00:12:01,350 Мы вызвалім нашы буфера і вяртае нуль. 193 00:12:01,350 --> 00:12:04,170 >> Нарэшце, мы дадаем знак у буфер. 194 00:12:04,170 --> 00:12:08,200 Як толькі карыстальнік націскае увядзіце або вярнуць, сігналізацыя з новага радка, 195 00:12:08,200 --> 00:12:12,050 або спецыяльны сімвал - кіраванне D - які сігналізуе пра канец ўводу, 196 00:12:12,050 --> 00:12:16,240 Мы робім праверку, каб убачыць, калі карыстач на самай справе набралі ні ў што. 197 00:12:16,240 --> 00:12:18,820 Калі няма, то мы вяртаем нуль. 198 00:12:18,820 --> 00:12:22,280 У адваротным выпадку, таму што наш буфер, верагодна, больш, чым трэба, 199 00:12:22,280 --> 00:12:24,830 У горшым выпадку гэта амаль удвая больш, чым нам трэба 200 00:12:24,830 --> 00:12:27,830 так як мы двойчы кожны раз, калі мы змяняны памер, 201 00:12:27,830 --> 00:12:31,840 мы робім новую копію радкі, выкарыстоўваючы толькі аб'ём, які нам патрэбны. 202 00:12:31,840 --> 00:12:34,220 Мы дадалі дадатковы 1 да таНос выкліку, 203 00:12:34,220 --> 00:12:37,810 так што ёсць прастора для спецыяльнага знака нулявога тэрмінатара - \ 0, 204 00:12:37,810 --> 00:12:41,990 якія мы дадаем у радок раз мы капіяваны ў астатніх персанажаў, 205 00:12:41,990 --> 00:12:45,060 выкарыстанне зЪгпсру замест зЬгсру 206 00:12:45,060 --> 00:12:48,830 так што мы можам дакладна ўказаць, колькі знакаў мы хочам скапіяваць. 207 00:12:48,830 --> 00:12:51,690 StrCpy капіюе, пакуль не сустрэне \ 0. 208 00:12:51,690 --> 00:12:55,740 Тады мы вызвалім нашы буфер і вярнуць копію з выклікалым абанентам. 209 00:12:55,740 --> 00:12:59,840 >> Хто ведаў, што такое простае на выгляд функцыя можа быць так складана? 210 00:12:59,840 --> 00:13:02,820 Цяпер вы ведаеце, што адбываецца ў CS50 бібліятэкі. 211 00:13:02,820 --> 00:13:06,470 >> Мяне клічуць Нейт Хардисон, і гэта CS50. 212 00:13:06,470 --> 00:13:08,350 [CS50.TV]