1 00:00:00,000 --> 00:00:02,490 [Powered by Google Translate] [CS50 Library] 2 00:00:02,490 --> 00:00:04,220 [Nate hardison] [Đại học Harvard] 3 00:00:04,220 --> 00:00:07,260 [Đây là CS50. CS50.TV] 4 00:00:07,260 --> 00:00:11,510 Thư viện CS50 là một công cụ hữu ích mà chúng tôi đã cài đặt trên thiết bị 5 00:00:11,510 --> 00:00:15,870 để làm cho nó dễ dàng hơn cho bạn để viết các chương trình nhắc nhở người sử dụng cho đầu vào. 6 00:00:15,870 --> 00:00:21,670 Trong video này, chúng tôi sẽ kéo rèm và nhìn vào những gì chính xác là trong thư viện CS50. 7 00:00:21,670 --> 00:00:25,520 >> Trong video vào thư viện C, chúng ta nói về cách bạn # bao gồm tiêu đề các tập tin 8 00:00:25,520 --> 00:00:27,570 của thư viện trong mã nguồn của bạn, 9 00:00:27,570 --> 00:00:31,150 và sau đó bạn liên kết với một tập tin thư viện nhị phân trong giai đoạn liên kết 10 00:00:31,150 --> 00:00:33,140 của quá trình biên dịch. 11 00:00:33,140 --> 00:00:36,440 Các tập tin tiêu đề chỉ định giao diện của thư viện. 12 00:00:36,440 --> 00:00:41,280 Nghĩa là, họ chi tiết tất cả các nguồn tài nguyên thư viện có sẵn để bạn sử dụng, 13 00:00:41,280 --> 00:00:45,250 như tờ khai chức năng, các hằng số, và các loại dữ liệu. 14 00:00:45,250 --> 00:00:48,890 Các tập tin thư viện nhị phân chứa thực hiện của thư viện, 15 00:00:48,890 --> 00:00:54,580 được biên dịch từ các tập tin tiêu đề của thư viện và thư viện c nguồn tập tin mã. 16 00:00:54,580 --> 00:00:59,820 >> Các tập tin thư viện nhị phân không phải là rất thú vị để xem xét vì nó, tốt, trong hệ nhị phân. 17 00:00:59,820 --> 00:01:03,300 Vì vậy, chúng ta hãy nhìn vào các tập tin tiêu đề cho thư viện thay vì. 18 00:01:03,300 --> 00:01:07,710 Trong trường hợp này, chỉ có một phần đầu tập tin được gọi là cs50.h. 19 00:01:07,710 --> 00:01:11,040 Chúng tôi đã cài đặt nó trong người sử dụng bao gồm thư mục 20 00:01:11,040 --> 00:01:15,150 cùng với các tập tin tiêu đề của hệ thống các thư viện khác. 21 00:01:15,150 --> 00:01:21,530 >> Một trong những điều đầu tiên bạn sẽ nhận thấy là cs50.h # bao gồm các tập tin tiêu đề từ các thư viện khác - 22 00:01:21,530 --> 00:01:25,670 float, giới hạn, tiêu chuẩn bool, và lib tiêu chuẩn. 23 00:01:25,670 --> 00:01:28,800 Một lần nữa, theo nguyên tắc không tái phát minh ra bánh xe, 24 00:01:28,800 --> 00:01:33,490 chúng tôi đã xây dựng thư viện CS0 bằng cách sử dụng các công cụ khác được cung cấp cho chúng tôi. 25 00:01:33,490 --> 00:01:38,690 >> Điều tiếp theo bạn sẽ thấy trong thư viện là chúng ta định nghĩa một kiểu mới được gọi là "chuỗi". 26 00:01:38,690 --> 00:01:42,330 Dòng này thực sự chỉ là tạo ra một bí danh cho các loại char *, 27 00:01:42,330 --> 00:01:46,000 do đó, nó không kỳ diệu niềm tự hào dân tộc các loại chuỗi mới với các thuộc tính 28 00:01:46,000 --> 00:01:49,650 thường liên kết với các đối tượng chuỗi trong các ngôn ngữ khác, 29 00:01:49,650 --> 00:01:50,850 chẳng hạn như chiều dài. 30 00:01:50,850 --> 00:01:55,180 Lý do chúng tôi đã làm điều này là để bảo vệ các lập trình mới từ các chi tiết đẫm máu 31 00:01:55,180 --> 00:01:57,580 của các con trỏ cho đến khi họ đã sẵn sàng. 32 00:01:57,580 --> 00:02:00,130 >> Các phần tiếp theo của tập tin header là khai báo các chức năng 33 00:02:00,130 --> 00:02:04,410 thư viện CS50 cung cấp cùng với các tài liệu. 34 00:02:04,410 --> 00:02:06,940 Chú ý mức độ chi tiết trong các ý kiến ​​ở đây. 35 00:02:06,940 --> 00:02:10,560 Điều này là siêu quan trọng để mọi người biết làm thế nào để sử dụng các chức năng này. 36 00:02:10,560 --> 00:02:19,150 Chúng tôi tuyên bố, lần lượt, chức năng nhắc nhở người sử dụng và các ký tự trở lại, tăng gấp đôi, phao, ints, 37 00:02:19,150 --> 00:02:24,160 dài chờ đợi, và chuỗi, bằng cách sử dụng loại dây riêng của chúng tôi. 38 00:02:24,160 --> 00:02:26,260 Theo nguyên tắc ẩn thông tin, 39 00:02:26,260 --> 00:02:31,640 chúng tôi đã đặt định nghĩa của chúng tôi trong một file riêng biệt thực hiện c - cs50.c - 40 00:02:31,640 --> 00:02:35,110 nằm trong thư mục nguồn của người dùng. 41 00:02:35,110 --> 00:02:38,040 Chúng tôi đã cung cấp tập tin để bạn có thể có một cái nhìn vào nó, 42 00:02:38,040 --> 00:02:41,490 học hỏi từ nó, và biên dịch lại nó trên các máy khác nhau nếu bạn muốn, 43 00:02:41,490 --> 00:02:45,510 mặc dù chúng ta nghĩ rằng nó tốt hơn để làm việc trên các thiết bị cho các lớp học này. 44 00:02:45,510 --> 00:02:47,580 Dù sao, chúng ta hãy có một cái nhìn vào nó bây giờ. 45 00:02:49,020 --> 00:02:54,620 >> Getchar, GetDouble, GetFloat, getInt, chức năng và GetLongLong 46 00:02:54,620 --> 00:02:58,160 tất cả đều được xây dựng trên đầu trang của các chức năng GetString. 47 00:02:58,160 --> 00:03:01,510 Nó chỉ ra rằng tất cả họ đều theo về cơ bản cùng một khuôn mẫu. 48 00:03:01,510 --> 00:03:04,870 Họ sử dụng một vòng lặp trong khi để nhắc nhở người dùng cho một dòng đầu vào. 49 00:03:04,870 --> 00:03:08,430 Họ trả về một giá trị đặc biệt nếu người sử dụng đầu vào một dòng trống. 50 00:03:08,430 --> 00:03:11,750 Họ cố gắng để phân tích đầu vào của người sử dụng như các loại thích hợp, 51 00:03:11,750 --> 00:03:15,010 có thể là, char một đôi, một phao, vv. 52 00:03:15,010 --> 00:03:18,710 Và sau đó họ có trả lại kết quả nếu đầu vào đã được phân tích thành công 53 00:03:18,710 --> 00:03:21,330 hoặc họ nhắc nhở lại cho người dùng. 54 00:03:21,330 --> 00:03:24,230 >> Ở mức độ cao, không có gì là thực sự khó khăn ở đây. 55 00:03:24,230 --> 00:03:28,760 Bạn có thể viết mã tương tự như cấu trúc mình trong quá khứ. 56 00:03:28,760 --> 00:03:34,720 Có lẽ một phần khó hiểu nhìn nhất là các cuộc gọi sscanf phân tích đầu vào của người dùng. 57 00:03:34,720 --> 00:03:38,160 Sscanf là một phần của gia đình chuyển đổi định dạng đầu vào. 58 00:03:38,160 --> 00:03:42,300 Nó sống trong tiêu chuẩn io.h, và công việc của mình để phân tích một chuỗi C, 59 00:03:42,300 --> 00:03:46,520 theo một định dạng cụ thể, lưu trữ các kết quả phân tích trong biến 60 00:03:46,520 --> 00:03:48,720 được cung cấp bởi người gọi. 61 00:03:48,720 --> 00:03:53,570 Kể từ khi chức năng chuyển đổi định dạng đầu vào là rất hữu ích, chức năng được sử dụng rộng rãi 62 00:03:53,570 --> 00:03:56,160 không phải là siêu trực quan ban đầu, 63 00:03:56,160 --> 00:03:58,300 chúng ta sẽ đi qua sscanf hoạt động như thế nào. 64 00:03:58,300 --> 00:04:03,330 >> Đối số đầu tiên để sscanf là một char * - một con trỏ đến một nhân vật. 65 00:04:03,330 --> 00:04:05,150 Đối với chức năng hoạt động đúng, 66 00:04:05,150 --> 00:04:08,340 rằng nhân vật phải là ký tự đầu tiên của một chuỗi C, 67 00:04:08,340 --> 00:04:12,270 chấm dứt với các ký tự null 0 \. 68 00:04:12,270 --> 00:04:15,120 Đây là một chuỗi để phân tích 69 00:04:15,120 --> 00:04:18,269 Đối số thứ hai để sscanf là một chuỗi định dạng, 70 00:04:18,269 --> 00:04:20,839 thường thông qua như là một hằng chuỗi, 71 00:04:20,839 --> 00:04:24,040 và bạn có thể đã thấy một chuỗi như thế này trước khi sử dụng printf. 72 00:04:24,040 --> 00:04:28,650 Một dấu hiệu% trong chuỗi định dạng cho thấy một xác định chuyển đổi. 73 00:04:28,650 --> 00:04:30,850 Các nhân vật ngay lập tức sau một dấu phần trăm, 74 00:04:30,850 --> 00:04:35,430 cho biết loại C mà chúng tôi muốn sscanf để chuyển đổi. 75 00:04:35,430 --> 00:04:40,090 GetInt, bạn thấy rằng có d% c%. 76 00:04:40,090 --> 00:04:48,690 Điều này có nghĩa là sscanf sẽ cố gắng để một int thập phân - d% và char c%. 77 00:04:48,690 --> 00:04:51,510 Đối với mỗi xác định chuyển đổi các chuỗi định dạng, 78 00:04:51,510 --> 00:04:56,620 sscanf hy vọng một đối số tương ứng sau đó trong danh sách đối số của nó. 79 00:04:56,620 --> 00:05:00,850 Lập luận phải trỏ đến một vị trí thích hợp đánh máy 80 00:05:00,850 --> 00:05:04,000 trong đó để lưu trữ các kết quả của việc chuyển đổi. 81 00:05:04,000 --> 00:05:08,910 >> Cách điển hình của việc này là để tạo ra một biến trên stack trước khi cuộc gọi sscanf 82 00:05:08,910 --> 00:05:11,440 cho mỗi mục mà bạn muốn phân tích từ chuỗi 83 00:05:11,440 --> 00:05:15,520 và sau đó sử dụng các nhà điều hành địa chỉ ký hiệu "- vượt qua con trỏ 84 00:05:15,520 --> 00:05:19,100 những biến cuộc gọi sscanf. 85 00:05:19,100 --> 00:05:22,720 Bạn có thể thấy rằng trong getInt chúng tôi làm chính xác này. 86 00:05:22,720 --> 00:05:28,240 Ngay trước khi cuộc gọi sscanf, chúng ta khai báo một int được gọi là n và gọi một c char trên stack, 87 00:05:28,240 --> 00:05:32,340 và chúng tôi vượt qua con trỏ cho họ vào các cuộc gọi sscanf. 88 00:05:32,340 --> 00:05:35,800 Đưa các biến trên stack được ưa thích hơn bằng cách sử dụng không gian phân bổ 89 00:05:35,800 --> 00:05:39,350 trên heap với malloc, kể từ khi bạn tránh những phí của các cuộc gọi malloc, 90 00:05:39,350 --> 00:05:43,060 và bạn không phải lo lắng về việc rò rỉ bộ nhớ. 91 00:05:43,060 --> 00:05:47,280 Nhân vật không bắt đầu bằng một dấu phần trăm không nhắc chuyển đổi. 92 00:05:47,280 --> 00:05:50,380 Thay vào đó họ chỉ cần thêm vào các đặc điểm kỹ thuật định dạng. 93 00:05:50,380 --> 00:05:56,500 >> Ví dụ, nếu các chuỗi định dạng trong getInt là một d% thay vào đó, 94 00:05:56,500 --> 00:05:59,800 sscanf sẽ tìm kiếm một lá thư tiếp theo là một int, 95 00:05:59,800 --> 00:06:04,360 và trong khi nó sẽ cố gắng để chuyển đổi các int, nó sẽ không làm bất cứ điều gì khác với một. 96 00:06:04,360 --> 00:06:07,440 Ngoại lệ duy nhất là khoảng trắng. 97 00:06:07,440 --> 00:06:11,030 Ký tự khoảng trắng trong chuỗi định dạng phù hợp với bất kỳ số lượng khoảng trắng - 98 00:06:11,030 --> 00:06:12,890 thậm chí không có gì cả. 99 00:06:12,890 --> 00:06:18,100 Vì vậy, đó là lý do tại sao các bình luận đề cập đến có thể có hàng đầu thế giới và / hoặc dấu khoảng trắng. 100 00:06:18,100 --> 00:06:22,910 Vì vậy, vào thời điểm này có vẻ như cuộc gọi sscanf của chúng tôi sẽ cố gắng phân tích chuỗi đầu vào của người dùng 101 00:06:22,910 --> 00:06:25,380 bằng cách kiểm tra để có thể hàng đầu khoảng trắng, 102 00:06:25,380 --> 00:06:29,300 tiếp theo là một int sẽ được chuyển đổi và lưu trữ trong các biến int n 103 00:06:29,300 --> 00:06:33,090 tiếp theo là một số lượng khoảng trắng, và tiếp theo là một nhân vật 104 00:06:33,090 --> 00:06:35,810 lưu trữ trong biến char c. 105 00:06:35,810 --> 00:06:37,790 >> Điều gì về giá trị trả lại? 106 00:06:37,790 --> 00:06:41,560 Sscanf sẽ phân tích các dòng đầu vào từ đầu đến cuối, 107 00:06:41,560 --> 00:06:44,860 dừng lại khi nó đạt đến kết thúc hoặc khi một nhân vật trong đầu vào 108 00:06:44,860 --> 00:06:49,320 không phù hợp với một ký tự định dạng hoặc khi nó không thể làm cho một chuyển đổi. 109 00:06:49,320 --> 00:06:52,690 Giá trị trả về của nó được sử dụng duy nhất khi nó dừng lại. 110 00:06:52,690 --> 00:06:55,670 Nếu nó dừng lại, bởi vì nó đạt đến kết thúc của chuỗi đầu vào 111 00:06:55,670 --> 00:07:00,630 trước khi thực hiện bất kỳ chuyển đổi và trước khi không phù hợp với một phần của chuỗi định dạng, 112 00:07:00,630 --> 00:07:04,840 sau đó kết thúc tập tin đặc biệt liên tục được trả về. 113 00:07:04,840 --> 00:07:08,200 Nếu không, nó trả về số chuyển đổi thành công, 114 00:07:08,200 --> 00:07:14,380 mà có thể là 0, 1, hoặc 2, kể từ khi chúng tôi đã yêu cầu hai chuyển đổi. 115 00:07:14,380 --> 00:07:19,000 Trong trường hợp của chúng tôi, chúng tôi muốn chắc chắn rằng người dùng gõ vào một int và chỉ có một int. 116 00:07:19,000 --> 00:07:23,370 >> Vì vậy, chúng tôi muốn sscanf để trở về 1. Xem tại sao? 117 00:07:23,370 --> 00:07:26,850 Nếu sscanf trở về 0, sau đó không có chuyển đổi đã được thực hiện, 118 00:07:26,850 --> 00:07:31,690 do đó, người dùng gõ một cái gì đó khác hơn nhiều so với một int tại đầu của đầu vào. 119 00:07:31,690 --> 00:07:37,100 Nếu sscanf trả về 2, sau đó người dùng không đúng cách gõ nó tại đầu của đầu vào, 120 00:07:37,100 --> 00:07:41,390 nhưng sau đó gõ một số ký tự không phải khoảng trắng sau đó 121 00:07:41,390 --> 00:07:44,940 kể từ khi% c chuyển đổi thành công. 122 00:07:44,940 --> 00:07:49,570 Wow, đó là một lời giải thích khá dài cho một cuộc gọi chức năng. 123 00:07:49,570 --> 00:07:53,460 Dù sao, nếu bạn muốn biết thêm thông tin trên sscanf, anh, chị, em ruột của nó, 124 00:07:53,460 --> 00:07:57,130 kiểm tra các trang người đàn ông, Google, hoặc cả hai. 125 00:07:57,130 --> 00:07:58,780 Có rất nhiều lựa chọn chuỗi định dạng, 126 00:07:58,780 --> 00:08:03,830 và chúng có thể giúp bạn tiết kiệm rất nhiều lao động thủ công khi cố gắng phân tích chuỗi trong C. 127 00:08:03,830 --> 00:08:07,180 >> Chức năng cuối cùng trong thư viện để xem xét là GetString. 128 00:08:07,180 --> 00:08:10,310 Nó chỉ ra rằng GetString là một chức năng khó khăn để viết đúng, 129 00:08:10,310 --> 00:08:14,290 mặc dù nó có vẻ như một nhiệm vụ đơn giản, phổ biến,. 130 00:08:14,290 --> 00:08:16,170 Tại sao điều này là trường hợp? 131 00:08:16,170 --> 00:08:21,380 Vâng, chúng ta hãy suy nghĩ về việc làm thế nào chúng ta sẽ để lưu trữ các dòng mà người dùng gõ vào. 132 00:08:21,380 --> 00:08:23,880 Kể từ khi một chuỗi là một chuỗi các ký tự, 133 00:08:23,880 --> 00:08:26,430 chúng tôi có thể muốn để lưu trữ nó trong một mảng trên stack, 134 00:08:26,430 --> 00:08:31,250 nhưng chúng tôi sẽ cần phải biết bao lâu các mảng là có được khi chúng ta khai báo nó. 135 00:08:31,250 --> 00:08:34,030 Tương tự như vậy, nếu chúng ta muốn đặt nó trên heap, 136 00:08:34,030 --> 00:08:38,090 chúng ta cần phải vượt qua để malloc số byte chúng ta muốn dự trữ, 137 00:08:38,090 --> 00:08:39,730 nhưng điều này là không thể. 138 00:08:39,730 --> 00:08:42,760 Chúng tôi không có ý tưởng bao nhiêu ký tự người dùng sẽ gõ vào 139 00:08:42,760 --> 00:08:46,590 trước khi người dùng thực sự không gõ. 140 00:08:46,590 --> 00:08:50,720 >> Một giải pháp ngây thơ cho vấn đề này là chỉ cần dự trữ một đoạn lớn của không gian, nói, 141 00:08:50,720 --> 00:08:54,540 một khối 1000 ký tự cho đầu vào của người dùng, 142 00:08:54,540 --> 00:08:57,980 giả định rằng người sử dụng không bao giờ sẽ nhập vào một chuỗi dài. 143 00:08:57,980 --> 00:09:00,810 Đây là một ý tưởng tồi vì hai lý do. 144 00:09:00,810 --> 00:09:05,280 Đầu tiên, giả định rằng người dùng thường không gõ trong chuỗi dài, 145 00:09:05,280 --> 00:09:07,610 bạn có thể lãng phí rất nhiều bộ nhớ. 146 00:09:07,610 --> 00:09:10,530 Trên máy móc hiện đại, điều này có thể không là một vấn đề nếu bạn làm điều này 147 00:09:10,530 --> 00:09:13,890 trong một hoặc hai trường hợp cá biệt, 148 00:09:13,890 --> 00:09:17,630 nhưng nếu bạn đang dùng đầu vào người sử dụng trong một vòng lặp và lưu trữ để sử dụng sau, 149 00:09:17,630 --> 00:09:20,870 bạn có thể nhanh chóng hút một tấn của bộ nhớ. 150 00:09:20,870 --> 00:09:24,450 Ngoài ra, nếu chương trình bạn đang viết cho một máy tính nhỏ hơn - 151 00:09:24,450 --> 00:09:28,100 một thiết bị giống như một điện thoại thông minh hoặc một cái gì đó khác với bộ nhớ hạn chế - 152 00:09:28,100 --> 00:09:32,060 giải pháp này sẽ gây ra vấn đề nhanh hơn rất nhiều. 153 00:09:32,060 --> 00:09:36,450 , Lý do thứ hai nghiêm trọng hơn để không làm điều này là nó rời khỏi chương trình của bạn dễ bị tổn thương 154 00:09:36,450 --> 00:09:39,710 những gì được gọi là một tấn công tràn bộ đệm. 155 00:09:39,710 --> 00:09:45,840 Trong lập trình, một bộ đệm là bộ nhớ được sử dụng để lưu trữ tạm thời dữ liệu đầu vào hoặc đầu ra, 156 00:09:45,840 --> 00:09:48,980 mà trong trường hợp này là khối 1000-char của chúng tôi. 157 00:09:48,980 --> 00:09:53,370 Một lỗi tràn bộ đệm xảy ra khi dữ liệu được ghi quá khứ kết thúc của khối. 158 00:09:53,370 --> 00:09:57,790 >> Ví dụ, nếu một người sử dụng thực hiện loại trong hơn 1000 ký tự. 159 00:09:57,790 --> 00:10:01,570 Bạn có thể đã có kinh nghiệm này vô tình khi lập trình với mảng. 160 00:10:01,570 --> 00:10:05,620 Nếu bạn có một mảng của 10 ints, không có gì ngăn bạn cố gắng để đọc hoặc viết 161 00:10:05,620 --> 00:10:07,810 int 15. 162 00:10:07,810 --> 00:10:10,000 Không có cảnh báo lỗi trình biên dịch hoặc. 163 00:10:10,000 --> 00:10:13,250 Chương trình chỉ sai lầm ngớ ngẩn thẳng về phía trước và truy cập bộ nhớ 164 00:10:13,250 --> 00:10:18,150 nơi nó nghĩ rằng int 15 sẽ được, và điều này có thể ghi đè lên các biến số khác của bạn. 165 00:10:18,150 --> 00:10:22,040 Trong trường hợp xấu nhất, bạn có thể ghi đè lên một số chương trình của bạn nội bộ 166 00:10:22,040 --> 00:10:26,820 cơ chế kiểm soát, gây ra chương trình của bạn thực sự thực hiện các hướng dẫn khác nhau 167 00:10:26,820 --> 00:10:28,340 hơn bạn dự định. 168 00:10:28,340 --> 00:10:31,360 >> Bây giờ, nó không phải là phổ biến để làm điều này vô tình, 169 00:10:31,360 --> 00:10:35,150 nhưng đây là một kỹ thuật khá phổ biến mà kẻ xấu sử dụng để phá vỡ chương trình 170 00:10:35,150 --> 00:10:39,080 và đặt mã độc hại trên máy tính của người khác. 171 00:10:39,080 --> 00:10:42,910 Vì vậy, chúng ta có thể không chỉ sử dụng giải pháp ngây thơ của chúng tôi. 172 00:10:42,910 --> 00:10:45,590 Chúng ta cần một cách để ngăn chặn các chương trình của chúng tôi là dễ bị tổn thương 173 00:10:45,590 --> 00:10:47,880 một cuộc tấn công tràn bộ đệm. 174 00:10:47,880 --> 00:10:51,430 Để làm điều này, chúng ta cần đảm bảo rằng bộ đệm của chúng tôi có thể phát triển như chúng ta đọc 175 00:10:51,430 --> 00:10:53,850 đầu vào từ người sử dụng. 176 00:10:53,850 --> 00:10:57,440 Các giải pháp? Chúng tôi sử dụng một bộ đệm được phân bổ đống. 177 00:10:57,440 --> 00:10:59,950 Từ khi chúng tôi có thể thay đổi kích thước nó bằng cách sử dụng các chức năng thay đổi kích cỡ realloc, 178 00:10:59,950 --> 00:11:04,580 và chúng tôi theo dõi của hai số - chỉ số của khe trống bên cạnh trong bộ đệm 179 00:11:04,580 --> 00:11:08,390 và chiều dài hoặc năng lực của bộ đệm. 180 00:11:08,390 --> 00:11:13,210 Chúng ta đọc trong các ký tự từ một người sử dụng tại một thời gian bằng cách sử dụng chức năng fgetc. 181 00:11:13,210 --> 00:11:19,360 Đối số chức năng fgetc mất - stdin - là một tham chiếu đến chuỗi đầu vào tiêu chuẩn, 182 00:11:19,360 --> 00:11:23,810 mà là một kênh đầu vào preconnected được sử dụng để chuyển đầu vào của người sử dụng 183 00:11:23,810 --> 00:11:26,270 từ các thiết bị đầu cuối cho chương trình. 184 00:11:26,270 --> 00:11:29,890 >> Bất cứ khi nào người sử dụng các loại trong một nhân vật mới, chúng tôi kiểm tra xem nếu các chỉ số 185 00:11:29,890 --> 00:11:35,810 của khe miễn phí tiếp theo cộng với 1 là lớn hơn dung lượng của bộ đệm. 186 00:11:35,810 --> 00:11:39,690 +1 Những có bởi vì nếu chỉ số miễn phí tiếp theo là 5, 187 00:11:39,690 --> 00:11:44,150 sau đó chiều dài của bộ đệm của chúng tôi phải là 6 đến 0 lập chỉ mục. 188 00:11:44,150 --> 00:11:48,350 Nếu chúng tôi đã chạy ra khỏi không gian trong bộ đệm, sau đó chúng tôi cố gắng để thay đổi kích cỡ của nó, 189 00:11:48,350 --> 00:11:51,690 tăng gấp đôi nó để chúng ta cắt giảm số lần mà chúng ta thay đổi kích thước 190 00:11:51,690 --> 00:11:54,760 nếu người dùng đang gõ vào một chuỗi thực sự dài. 191 00:11:54,760 --> 00:11:57,950 Nếu chuỗi đã nhận được quá lâu hoặc nếu chúng ta chạy ra khỏi bộ nhớ heap, 192 00:11:57,950 --> 00:12:01,350 chúng tôi miễn phí bộ đệm của chúng tôi và vô giá trị trở lại. 193 00:12:01,350 --> 00:12:04,170 >> Cuối cùng, chúng ta nối char vào bộ đệm. 194 00:12:04,170 --> 00:12:08,200 Một khi các số truy cập của người dùng vào hoặc trở lại, báo hiệu một dòng mới, 195 00:12:08,200 --> 00:12:12,050 hoặc char đặc biệt kiểm soát d - dấu sự kết thúc của đầu vào, 196 00:12:12,050 --> 00:12:16,240 chúng tôi làm một kiểm tra để xem nếu người sử dụng thực sự gõ vào bất cứ điều gì ở tất cả. 197 00:12:16,240 --> 00:12:18,820 Nếu không, chúng tôi trở về null. 198 00:12:18,820 --> 00:12:22,280 Nếu không, bởi vì bộ đệm của chúng tôi có lẽ lớn hơn chúng ta cần, 199 00:12:22,280 --> 00:12:24,830 trong trường hợp xấu nhất, nó gần như hai lần lớn như chúng ta cần 200 00:12:24,830 --> 00:12:27,830 kể từ khi chúng tôi tăng gấp đôi mỗi khi chúng ta thay đổi kích thước, 201 00:12:27,830 --> 00:12:31,840 chúng tôi thực hiện một bản sao mới của chuỗi bằng cách sử dụng chỉ là số tiền của không gian mà chúng ta cần. 202 00:12:31,840 --> 00:12:34,220 Chúng tôi thêm một thêm 1 cuộc gọi malloc, 203 00:12:34,220 --> 00:12:37,810 để có không gian cho các ký tự đặc biệt terminator vô giá trị - \ 0, 204 00:12:37,810 --> 00:12:41,990 mà chúng ta nối chuỗi một khi chúng ta sao chép trong phần còn lại của các nhân vật, 205 00:12:41,990 --> 00:12:45,060 sử dụng strncpy thay vì strcpy 206 00:12:45,060 --> 00:12:48,830 để chúng tôi có thể xác định chính xác có bao nhiêu ký tự chúng ta muốn sao chép. 207 00:12:48,830 --> 00:12:51,690 Strcpy sao chép cho đến khi nó cập một \ 0. 208 00:12:51,690 --> 00:12:55,740 Sau đó, chúng tôi miễn phí bộ đệm của chúng tôi và trả lại các bản sao để người gọi. 209 00:12:55,740 --> 00:12:59,840 >> Ai biết như một chức năng đơn giản, dường như có thể được như vậy phức tạp? 210 00:12:59,840 --> 00:13:02,820 Bây giờ bạn biết những gì đi vào thư viện CS50. 211 00:13:02,820 --> 00:13:06,470 >> Tên tôi là Nate hardison, và đây là CS50. 212 00:13:06,470 --> 00:13:08,350 [CS50.TV]