1 00:00:00,000 --> 00:00:02,490 [Powered by Google Translate] [CS50 Perpustakaan] 2 00:00:02,490 --> 00:00:04,220 [Nate Hardison] [Harvard University] 3 00:00:04,220 --> 00:00:07,260 [Ini adalah CS50. CS50.TV] 4 00:00:07,260 --> 00:00:11,510 Perpustakaan CS50 adalah alat yang berguna yang kita telah diinstal pada alat 5 00:00:11,510 --> 00:00:15,870 untuk membuatnya lebih mudah bagi Anda untuk menulis program yang meminta pengguna untuk input. 6 00:00:15,870 --> 00:00:21,670 Dalam video ini, kita akan menarik kembali tirai dan melihat apa sebenarnya di perpustakaan CS50. 7 00:00:21,670 --> 00:00:25,520 >> Dalam video pada library C, kita berbicara tentang bagaimana Anda menyertakan file header # 8 00:00:25,520 --> 00:00:27,570 dari perpustakaan dalam kode sumber Anda, 9 00:00:27,570 --> 00:00:31,150 dan kemudian Anda menghubungkan dengan file library biner selama fase menghubungkan 10 00:00:31,150 --> 00:00:33,140 dari proses kompilasi. 11 00:00:33,140 --> 00:00:36,440 File header menentukan antarmuka dari perpustakaan. 12 00:00:36,440 --> 00:00:41,280 Artinya, mereka detail semua sumber daya yang perpustakaan telah tersedia untuk Anda gunakan, 13 00:00:41,280 --> 00:00:45,250 seperti deklarasi fungsi, konstanta, dan tipe data. 14 00:00:45,250 --> 00:00:48,890 File library biner berisi implementasi dari perpustakaan, 15 00:00:48,890 --> 00:00:54,580 yang disusun dari file header perpustakaan dan perpustakaan file sumber. kode c. 16 00:00:54,580 --> 00:00:59,820 >> File library biner tidak sangat menarik untuk melihat karena itu, baik, dalam biner. 17 00:00:59,820 --> 00:01:03,300 Jadi, mari kita lihat di file header untuk perpustakaan sebagai gantinya. 18 00:01:03,300 --> 00:01:07,710 Dalam kasus ini, hanya ada satu header file bernama cs50.h. 19 00:01:07,710 --> 00:01:11,040 Kami telah diinstal di pengguna termasuk direktori 20 00:01:11,040 --> 00:01:15,150 bersama dengan file header perpustakaan sistem lainnya '. 21 00:01:15,150 --> 00:01:21,530 >> Salah satu hal pertama yang akan Anda perhatikan adalah bahwa cs50.h # termasuk file header dari perpustakaan lain - 22 00:01:21,530 --> 00:01:25,670 float, batas, standar bool, dan lib standar. 23 00:01:25,670 --> 00:01:28,800 Sekali lagi, mengikuti prinsip tidak menciptakan kembali roda, 24 00:01:28,800 --> 00:01:33,490 kami telah membangun perpustakaan CS0 menggunakan alat-alat yang lain yang disediakan bagi kita. 25 00:01:33,490 --> 00:01:38,690 >> Hal berikutnya yang Anda akan melihat di perpustakaan adalah bahwa kita mendefinisikan sebuah tipe baru yang disebut "string." 26 00:01:38,690 --> 00:01:42,330 Baris ini benar-benar hanya menciptakan sebuah alias untuk jenis char *, 27 00:01:42,330 --> 00:01:46,000 sehingga tidak ajaib mengilhami tipe string baru dengan atribut 28 00:01:46,000 --> 00:01:49,650 umumnya terkait dengan objek string dalam bahasa lain, 29 00:01:49,650 --> 00:01:50,850 seperti panjang. 30 00:01:50,850 --> 00:01:55,180 Alasan kita lakukan ini adalah untuk melindungi programmer baru dari rincian berdarah 31 00:01:55,180 --> 00:01:57,580 dari pointer sampai mereka siap. 32 00:01:57,580 --> 00:02:00,130 >> Bagian berikutnya dari file header deklarasi fungsi 33 00:02:00,130 --> 00:02:04,410 bahwa perpustakaan CS50 menyediakan bersama dengan dokumentasi. 34 00:02:04,410 --> 00:02:06,940 Perhatikan tingkat rincian dalam komentar di sini. 35 00:02:06,940 --> 00:02:10,560 Ini adalah super penting agar orang tahu bagaimana menggunakan fungsi-fungsi ini. 36 00:02:10,560 --> 00:02:19,150 Kami menyatakan, pada gilirannya, berfungsi untuk meminta pengguna dan karakter kembali, ganda, mengapung, ints, 37 00:02:19,150 --> 00:02:24,160 lama rindu, dan string, menggunakan tipe string kita sendiri. 38 00:02:24,160 --> 00:02:26,260 Mengikuti prinsip menyembunyikan informasi, 39 00:02:26,260 --> 00:02:31,640 kami telah menempatkan definisi kita dalam file terpisah implementasi c -. cs50.c-- 40 00:02:31,640 --> 00:02:35,110 terletak di direktori source pengguna. 41 00:02:35,110 --> 00:02:38,040 Kami telah menyediakan file tersebut sehingga Anda dapat melihat hal itu, 42 00:02:38,040 --> 00:02:41,490 belajar dari itu, dan mengkompilasi ulang pada mesin yang berbeda jika Anda ingin, 43 00:02:41,490 --> 00:02:45,510 meskipun kita pikir lebih baik untuk bekerja pada alat untuk kelas ini. 44 00:02:45,510 --> 00:02:47,580 Pokoknya, mari kita lihat sekarang. 45 00:02:49,020 --> 00:02:54,620 >> Fungsi getchar, GetDouble, GetFloat, GetInt, dan GetLongLong 46 00:02:54,620 --> 00:02:58,160 semuanya dibangun di atas fungsi GetString. 47 00:02:58,160 --> 00:03:01,510 Ternyata bahwa mereka semua mengikuti pola yang sama dasarnya. 48 00:03:01,510 --> 00:03:04,870 Mereka menggunakan loop sementara untuk meminta pengguna untuk satu baris masukan. 49 00:03:04,870 --> 00:03:08,430 Mereka mengembalikan nilai khusus jika pengguna masukan sebuah baris kosong. 50 00:03:08,430 --> 00:03:11,750 Mereka berusaha untuk mengurai masukan pengguna sebagai jenis yang sesuai, 51 00:03:11,750 --> 00:03:15,010 baik itu, char ganda, pelampung, dll 52 00:03:15,010 --> 00:03:18,710 Dan kemudian mereka baik kembali hasilnya jika input berhasil diurai 53 00:03:18,710 --> 00:03:21,330 atau mereka reprompt pengguna. 54 00:03:21,330 --> 00:03:24,230 >> Pada tingkat tinggi, tidak ada yang benar-benar rumit di sini. 55 00:03:24,230 --> 00:03:28,760 Anda mungkin telah menulis kode terstruktur sama diri sendiri di masa lalu. 56 00:03:28,760 --> 00:03:34,720 Mungkin bagian yang paling samar yang tampak adalah panggilan sscanf yang mem-parsing input pengguna. 57 00:03:34,720 --> 00:03:38,160 Sscanf merupakan bagian dari keluarga format masukan konversi. 58 00:03:38,160 --> 00:03:42,300 Ia tinggal di io.h standar, dan tugasnya adalah untuk mengurai string C, 59 00:03:42,300 --> 00:03:46,520 sesuai dengan format tertentu, menyimpan hasil parse dalam variabel 60 00:03:46,520 --> 00:03:48,720 disediakan oleh pemanggil. 61 00:03:48,720 --> 00:03:53,570 Karena fungsi konversi format masukan yang sangat berguna, fungsi banyak digunakan 62 00:03:53,570 --> 00:03:56,160 yang tidak super intuitif pada awalnya, 63 00:03:56,160 --> 00:03:58,300 kita akan pergi atas bagaimana sscanf bekerja. 64 00:03:58,300 --> 00:04:03,330 >> Argumen pertama yang sscanf adalah char * - pointer ke karakter. 65 00:04:03,330 --> 00:04:05,150 Untuk fungsi untuk bekerja dengan baik, 66 00:04:05,150 --> 00:04:08,340 karakter yang harus menjadi karakter pertama dari string C, 67 00:04:08,340 --> 00:04:12,270 diakhiri dengan karakter \ nol 0. 68 00:04:12,270 --> 00:04:15,120 Ini adalah string untuk mengurai 69 00:04:15,120 --> 00:04:18,269 Argumen kedua sscanf adalah format string, 70 00:04:18,269 --> 00:04:20,839 biasanya berlalu dalam sebagai konstanta string, 71 00:04:20,839 --> 00:04:24,040 dan Anda mungkin telah melihat string seperti ini sebelumnya ketika menggunakan printf. 72 00:04:24,040 --> 00:04:28,650 Sebuah tanda persen dalam format string menunjukkan specifier konversi. 73 00:04:28,650 --> 00:04:30,850 Karakter segera setelah tanda persen, 74 00:04:30,850 --> 00:04:35,430 menunjukkan tipe C yang kita inginkan sscanf untuk mengkonversi ke. 75 00:04:35,430 --> 00:04:40,090 Dalam GetInt, Anda melihat bahwa ada% d dan c%. 76 00:04:40,090 --> 00:04:48,690 Ini berarti bahwa sscanf akan mencoba untuk int desimal -% d - dan char - c%. 77 00:04:48,690 --> 00:04:51,510 Untuk setiap specifier konversi dalam format string, 78 00:04:51,510 --> 00:04:56,620 sscanf mengharapkan argumen yang sesuai kemudian dalam daftar argumen. 79 00:04:56,620 --> 00:05:00,850 Argumen yang harus menunjuk ke lokasi yang tepat diketik 80 00:05:00,850 --> 00:05:04,000 di mana untuk menyimpan hasil konversi. 81 00:05:04,000 --> 00:05:08,910 >> Cara khas untuk melakukan hal ini adalah untuk membuat variabel pada stack sebelum panggilan sscanf 82 00:05:08,910 --> 00:05:11,440 untuk setiap item yang Anda ingin mengurai dari string 83 00:05:11,440 --> 00:05:15,520 dan kemudian menggunakan operator alamat - ampersand - untuk lulus pointer 84 00:05:15,520 --> 00:05:19,100 untuk variabel ke panggilan sscanf. 85 00:05:19,100 --> 00:05:22,720 Anda dapat melihat bahwa dalam GetInt kita melakukan hal ini. 86 00:05:22,720 --> 00:05:28,240 Tepat sebelum panggilan sscanf, kami mendeklarasikan int disebut n dan c char pada panggilan stack, 87 00:05:28,240 --> 00:05:32,340 dan kami melewati pointer ke mereka ke dalam panggilan sscanf. 88 00:05:32,340 --> 00:05:35,800 Menempatkan variabel-variabel pada stack lebih disukai daripada menggunakan ruang yang dialokasikan 89 00:05:35,800 --> 00:05:39,350 pada tumpukan dengan malloc, karena Anda menghindari overhead dari panggilan malloc, 90 00:05:39,350 --> 00:05:43,060 dan Anda tidak perlu khawatir tentang kebocoran memori. 91 00:05:43,060 --> 00:05:47,280 Karakter tidak diawali dengan tanda persen tidak meminta konversi. 92 00:05:47,280 --> 00:05:50,380 Sebaliknya mereka hanya menambah spesifikasi format. 93 00:05:50,380 --> 00:05:56,500 >> Misalnya, jika format string di GetInt adalah% d sebaliknya, 94 00:05:56,500 --> 00:05:59,800 sscanf akan mencari surat diikuti oleh int, 95 00:05:59,800 --> 00:06:04,360 dan sementara itu akan berusaha untuk mengkonversi int, itu tidak akan melakukan hal lain dengan itu. 96 00:06:04,360 --> 00:06:07,440 Satu-satunya pengecualian untuk ini adalah spasi. 97 00:06:07,440 --> 00:06:11,030 Karakter spasi dalam format string dapat ditemukan pada jumlah spasi - 98 00:06:11,030 --> 00:06:12,890 bahkan tidak sama sekali. 99 00:06:12,890 --> 00:06:18,100 Jadi, itu sebabnya komentar menyebutkan mungkin dengan memimpin dan / atau trailing spasi. 100 00:06:18,100 --> 00:06:22,910 Jadi, pada titik ini sepertinya panggilan sscanf kami akan mencoba untuk mengurai string masukan pengguna 101 00:06:22,910 --> 00:06:25,380 dengan memeriksa spasi terkemuka mungkin, 102 00:06:25,380 --> 00:06:29,300 diikuti oleh int yang akan dikonversi dan disimpan dalam variabel n int 103 00:06:29,300 --> 00:06:33,090 diikuti oleh beberapa jumlah spasi, dan diikuti oleh karakter 104 00:06:33,090 --> 00:06:35,810 disimpan dalam variabel char c. 105 00:06:35,810 --> 00:06:37,790 >> Bagaimana dengan nilai kembali? 106 00:06:37,790 --> 00:06:41,560 Sscanf akan mengurai baris masukan dari awal sampai akhir, 107 00:06:41,560 --> 00:06:44,860 berhenti ketika mencapai akhir atau ketika karakter dalam input 108 00:06:44,860 --> 00:06:49,320 tidak cocok dengan karakter format atau ketika tidak bisa membuat konversi. 109 00:06:49,320 --> 00:06:52,690 Nilai kembali itu digunakan untuk satu-ketika berhenti. 110 00:06:52,690 --> 00:06:55,670 Jika berhenti, karena mencapai akhir dari string masukan 111 00:06:55,670 --> 00:07:00,630 sebelum melakukan konversi dan sebelum gagal untuk mencocokkan bagian dari format string, 112 00:07:00,630 --> 00:07:04,840 maka EOF konstan khusus dikembalikan. 113 00:07:04,840 --> 00:07:08,200 Jika tidak, ia mengembalikan jumlah konversi yang berhasil, 114 00:07:08,200 --> 00:07:14,380 yang bisa 0, 1, atau 2, karena kita sudah meminta dua konversi. 115 00:07:14,380 --> 00:07:19,000 Dalam kasus kami, kami ingin memastikan bahwa pengguna mengetik int dan hanya int. 116 00:07:19,000 --> 00:07:23,370 >> Jadi, kami ingin sscanf kembali 1. Melihat mengapa? 117 00:07:23,370 --> 00:07:26,850 Jika sscanf kembali 0, maka tidak ada konversi dibuat, 118 00:07:26,850 --> 00:07:31,690 sehingga pengguna mengetik sesuatu selain int pada awal input. 119 00:07:31,690 --> 00:07:37,100 Jika sscanf kembali 2, maka pengguna tidak benar mengetikkannya pada awal input, 120 00:07:37,100 --> 00:07:41,390 tetapi mereka kemudian diketik dalam beberapa karakter non-spasi setelah 121 00:07:41,390 --> 00:07:44,940 karena% c konversi berhasil. 122 00:07:44,940 --> 00:07:49,570 Wow, itu cukup penjelasan panjang untuk satu fungsi panggil. 123 00:07:49,570 --> 00:07:53,460 Lagi pula, jika Anda ingin informasi lebih lanjut tentang sscanf dan turunannya, 124 00:07:53,460 --> 00:07:57,130 periksa halaman manual, Google, atau keduanya. 125 00:07:57,130 --> 00:07:58,780 Ada banyak pilihan format string, 126 00:07:58,780 --> 00:08:03,830 dan ini dapat menghemat banyak tenaga kerja manual ketika mencoba untuk mengurai string di C. 127 00:08:03,830 --> 00:08:07,180 >> Fungsi terakhir di perpustakaan untuk lihat adalah GetString. 128 00:08:07,180 --> 00:08:10,310 Ternyata GetString adalah fungsi sulit untuk menulis dengan baik, 129 00:08:10,310 --> 00:08:14,290 meskipun tampaknya seperti tugas sederhana, umum. 130 00:08:14,290 --> 00:08:16,170 Mengapa hal ini terjadi? 131 00:08:16,170 --> 00:08:21,380 Nah, mari kita berpikir tentang bagaimana kita akan menyimpan garis bahwa pengguna jenis masuk 132 00:08:21,380 --> 00:08:23,880 Karena string adalah urutan karakter, 133 00:08:23,880 --> 00:08:26,430 kita mungkin ingin menyimpannya dalam array di stack, 134 00:08:26,430 --> 00:08:31,250 tapi kita perlu tahu berapa lama array akan menjadi saat mendeklarasikannya. 135 00:08:31,250 --> 00:08:34,030 Demikian juga, jika kita ingin meletakkannya di heap, 136 00:08:34,030 --> 00:08:38,090 kita perlu untuk lolos ke malloc jumlah byte kita ingin cadangan, 137 00:08:38,090 --> 00:08:39,730 tapi ini tidak mungkin. 138 00:08:39,730 --> 00:08:42,760 Kami tidak tahu berapa banyak karakter pengguna akan ketik 139 00:08:42,760 --> 00:08:46,590 sebelum pengguna sebenarnya tidak mengetiknya. 140 00:08:46,590 --> 00:08:50,720 >> Sebuah solusi naif untuk masalah ini adalah dengan hanya memesan sebagian besar dari ruang, katakanlah, 141 00:08:50,720 --> 00:08:54,540 blok dari 1000 karakter untuk input pengguna, 142 00:08:54,540 --> 00:08:57,980 dengan asumsi bahwa pengguna tidak akan pernah ketik dalam string yang panjang. 143 00:08:57,980 --> 00:09:00,810 Ini adalah ide yang buruk karena dua alasan. 144 00:09:00,810 --> 00:09:05,280 Pertama, dengan asumsi bahwa pengguna biasanya tidak mengetikkan string yang lama, 145 00:09:05,280 --> 00:09:07,610 Anda bisa membuang banyak memori. 146 00:09:07,610 --> 00:09:10,530 Pada mesin modern, hal ini mungkin tidak menjadi masalah jika Anda melakukan hal ini 147 00:09:10,530 --> 00:09:13,890 dalam satu atau dua kasus yang terisolasi, 148 00:09:13,890 --> 00:09:17,630 tetapi jika Anda mengambil masukan pengguna dalam satu lingkaran dan menyimpan untuk digunakan nanti, 149 00:09:17,630 --> 00:09:20,870 Anda dapat dengan cepat menyedot ton memori. 150 00:09:20,870 --> 00:09:24,450 Selain itu, jika program Anda menulis adalah untuk komputer yang lebih kecil - 151 00:09:24,450 --> 00:09:28,100 perangkat seperti smartphone atau sesuatu yang lain dengan memori terbatas - 152 00:09:28,100 --> 00:09:32,060 solusi ini akan menimbulkan masalah jauh lebih cepat. 153 00:09:32,060 --> 00:09:36,450 Alasan kedua yang lebih serius untuk tidak melakukan hal ini adalah bahwa ia meninggalkan program anda rentan 154 00:09:36,450 --> 00:09:39,710 untuk apa yang disebut serangan buffer overflow. 155 00:09:39,710 --> 00:09:45,840 Dalam pemrograman, buffer adalah memori yang digunakan untuk menyimpan data sementara input atau output, 156 00:09:45,840 --> 00:09:48,980 yang dalam hal ini adalah 1000-char blok kami. 157 00:09:48,980 --> 00:09:53,370 Sebuah buffer overflow terjadi ketika data ditulis melewati ujung blok. 158 00:09:53,370 --> 00:09:57,790 >> Misalnya, jika pengguna sebenarnya ketik lebih dari 1000 karakter. 159 00:09:57,790 --> 00:10:01,570 Anda mungkin pernah mengalami hal ini sengaja ketika pemrograman dengan array. 160 00:10:01,570 --> 00:10:05,620 Jika Anda memiliki sebuah array dari 10 ints, tidak ada yang menghentikan Anda dari mencoba untuk membaca atau menulis 161 00:10:05,620 --> 00:10:07,810 int 15. 162 00:10:07,810 --> 00:10:10,000 Ada peringatan kompilator tidak ada atau kesalahan. 163 00:10:10,000 --> 00:10:13,250 Program ini hanya kesalahan lurus ke depan dan mengakses memori 164 00:10:13,250 --> 00:10:18,150 di mana ia berpikir int 15 akan, dan ini dapat menimpa variabel lain. 165 00:10:18,150 --> 00:10:22,040 Dalam kasus terburuk, Anda dapat menimpa beberapa internal program Anda 166 00:10:22,040 --> 00:10:26,820 mekanisme kontrol, menyebabkan program Anda untuk benar-benar menjalankan instruksi yang berbeda 167 00:10:26,820 --> 00:10:28,340 dari yang Anda inginkan. 168 00:10:28,340 --> 00:10:31,360 >> Sekarang, itu tidak umum untuk melakukan hal ini sengaja, 169 00:10:31,360 --> 00:10:35,150 tapi ini adalah teknik yang cukup umum bahwa orang-orang jahat gunakan untuk memecahkan program 170 00:10:35,150 --> 00:10:39,080 dan menempatkan kode berbahaya pada komputer orang lain. 171 00:10:39,080 --> 00:10:42,910 Oleh karena itu, kita tidak bisa hanya menggunakan solusi naif kami. 172 00:10:42,910 --> 00:10:45,590 Kita perlu cara untuk mencegah program kami dari menjadi rentan 173 00:10:45,590 --> 00:10:47,880 untuk serangan buffer overflow. 174 00:10:47,880 --> 00:10:51,430 Untuk melakukan hal ini, kita perlu memastikan bahwa buffer kita bisa tumbuh seperti yang kita baca 175 00:10:51,430 --> 00:10:53,850 lebih masukan dari pengguna. 176 00:10:53,850 --> 00:10:57,440 Solusinya? Kami menggunakan buffer dialokasikan tumpukan. 177 00:10:57,440 --> 00:10:59,950 Karena kita dapat mengubah ukurannya dengan menggunakan mengubah ukuran fungsi realloc, 178 00:10:59,950 --> 00:11:04,580 dan kami melacak dua angka - indeks slot kosong berikutnya dalam buffer 179 00:11:04,580 --> 00:11:08,390 dan panjang atau kapasitas buffer. 180 00:11:08,390 --> 00:11:13,210 Kita membaca dalam karakter dari pengguna satu per satu menggunakan fungsi fgetc. 181 00:11:13,210 --> 00:11:19,360 Argumen fungsi fgetc mengambil - stdin - adalah referensi ke string input standar, 182 00:11:19,360 --> 00:11:23,810 yang merupakan saluran masukan preconnected yang digunakan untuk mentransfer masukan pengguna 183 00:11:23,810 --> 00:11:26,270 dari terminal ke program. 184 00:11:26,270 --> 00:11:29,890 >> Setiap kali pengguna jenis dalam karakter baru, kita periksa untuk melihat apakah indeks 185 00:11:29,890 --> 00:11:35,810 dari slot free berikutnya ditambah 1 lebih besar dari kapasitas buffer. 186 00:11:35,810 --> 00:11:39,690 The +1 datang karena jika indeks bebas berikutnya adalah 5, 187 00:11:39,690 --> 00:11:44,150 maka panjang buffer kita harus 6 berkat 0 pengindeksan. 188 00:11:44,150 --> 00:11:48,350 Jika kita sudah kehabisan ruang dalam buffer, maka kita berusaha untuk mengubah ukurannya, 189 00:11:48,350 --> 00:11:51,690 menggandakan sehingga kita mengurangi jumlah kali bahwa kita mengubah ukuran 190 00:11:51,690 --> 00:11:54,760 jika pengguna mengetikkan string sangat panjang. 191 00:11:54,760 --> 00:11:57,950 Jika string yang sudah terlalu lama atau jika kita kehabisan memori heap, 192 00:11:57,950 --> 00:12:01,350 kita membebaskan penyangga dan nol kembali. 193 00:12:01,350 --> 00:12:04,170 >> Akhirnya, kita tambahkan char ke buffer. 194 00:12:04,170 --> 00:12:08,200 Setelah hits pengguna memasuki atau kembali, menandakan baris baru, 195 00:12:08,200 --> 00:12:12,050 atau char khusus - control d - yang merupakan sinyal dari akhir masukan, 196 00:12:12,050 --> 00:12:16,240 kita melakukan cek untuk melihat apakah pengguna benar-benar mengetik apa-apa. 197 00:12:16,240 --> 00:12:18,820 Jika tidak, kita kembali nol. 198 00:12:18,820 --> 00:12:22,280 Jika tidak, karena penyangga kami mungkin lebih besar daripada yang kita butuhkan, 199 00:12:22,280 --> 00:12:24,830 dalam kasus terburuk itu hampir dua kali lebih besar seperti yang kita butuhkan 200 00:12:24,830 --> 00:12:27,830 karena kita dua kali lipat setiap kali kita mengubah ukuran, 201 00:12:27,830 --> 00:12:31,840 kita membuat salinan baru dari string hanya menggunakan jumlah ruang yang kita butuhkan. 202 00:12:31,840 --> 00:12:34,220 Kami menambahkan 1 ekstra untuk panggilan malloc, 203 00:12:34,220 --> 00:12:37,810 sehingga ada ruang untuk karakter khusus terminator nol - yang \ 0, 204 00:12:37,810 --> 00:12:41,990 yang kita tambahkan ke string setelah kita copy di seluruh karakter, 205 00:12:41,990 --> 00:12:45,060 menggunakan strncpy bukan strcpy 206 00:12:45,060 --> 00:12:48,830 sehingga kita dapat menentukan dengan tepat berapa banyak karakter yang ingin kita copy. 207 00:12:48,830 --> 00:12:51,690 Strcpy salinan sampai hits \ 0. 208 00:12:51,690 --> 00:12:55,740 Kemudian kita membebaskan penyangga kami dan mengembalikan salinan ke pemanggil. 209 00:12:55,740 --> 00:12:59,840 >> Siapa yang tahu seperti fungsi sederhana-tampak bisa begitu rumit? 210 00:12:59,840 --> 00:13:02,820 Sekarang Anda tahu apa yang masuk ke perpustakaan CS50. 211 00:13:02,820 --> 00:13:06,470 >> Nama saya Nate Hardison, dan ini adalah CS50. 212 00:13:06,470 --> 00:13:08,350 [CS50.TV]