1 00:00:00,000 --> 00:00:00,180 2 00:00:00,180 --> 00:00:02,920 >> SPEAKER 1: Hãy viết một chương trình được một chuỗi từ người sử dụng mà không cần 3 00:00:02,920 --> 00:00:05,700 sử dụng Thư viện của CS50 chức năng GetString. 4 00:00:05,700 --> 00:00:08,720 Để làm điều này, chúng tôi sẽ đi trước và sử dụng scanf, chức năng rằng GetString 5 00:00:08,720 --> 00:00:10,950 chức năng thực sự sử dụng bên dưới mui xe. 6 00:00:10,950 --> 00:00:13,780 Nhưng tôi sẽ làm điều này cố tình một cách lỗi. 7 00:00:13,780 --> 00:00:17,230 Tôi sẽ làm theo một cách mà tôi nghĩ rằng sẽ là đúng, nhưng nó quay ra rằng 8 00:00:17,230 --> 00:00:19,380 giả định của tôi sẽ được khá, khá sai lầm. 9 00:00:19,380 --> 00:00:20,800 Và trong thực tế, khá nguy hiểm. 10 00:00:20,800 --> 00:00:24,750 Vì lỗi như một trong những tôi về để thực có thể được khai thác bởi các đối thủ 11 00:00:24,750 --> 00:00:28,870 như vậy mà máy tính của bạn hoặc chương trình của bạn có thể được thực hiện trên có khả năng. 12 00:00:28,870 --> 00:00:30,200 >> Hãy bắt đầu như sau. 13 00:00:30,200 --> 00:00:33,540 Đầu tiên hãy khai báo chuỗi của chúng tôi, nếu bây giờ được biết đến như một ngôi sao char, 14 00:00:33,540 --> 00:00:34,750 và gọi nó s. 15 00:00:34,750 --> 00:00:39,400 Cho phép tiếp theo nhắc nhở người dùng cho một chuỗi, như với "chuỗi xin vui lòng." Và 16 00:00:39,400 --> 00:00:44,250 bây giờ chúng ta có được những chuỗi từ người sử dụng sử dụng scanf, báo giá unquote, "% s". Trong 17 00:00:44,250 --> 00:00:47,760 Nói cách khác, chúng ta hãy thông báo cho chúng tôi rằng scanf trên thực tế có hy vọng để có được một chuỗi 18 00:00:47,760 --> 00:00:48,630 từ người sử dụng. 19 00:00:48,630 --> 00:00:50,810 >> Nhưng bây giờ chúng tôi cần phải nói cho scanf một điều khác - 20 00:00:50,810 --> 00:00:53,350 nơi để đặt các chuỗi người dùng cung cấp. 21 00:00:53,350 --> 00:00:57,840 Vâng, tôi sẽ khá đơn giản bắt đầu với dấu phẩy s, quy định cụ thể mà tôi muốn 22 00:00:57,840 --> 00:00:59,320 scanf để đặt chuỗi đó. 23 00:00:59,320 --> 00:01:04,818 Tôi tiếp theo sẽ in ra một cái gì đó như printf "cảm ơn cho% s 24 00:01:04,818 --> 00:01:10,670 dấu gạch chéo ngược n dấu phẩy. "Và như mọi khi, tôi sẽ vượt qua trong chuỗi, s. 25 00:01:10,670 --> 00:01:14,920 Bây giờ chúng ta tiết kiệm, biên dịch và chạy chương trình, và xem nếu chúng ta không có thể gây ra 26 00:01:14,920 --> 00:01:16,590 vấn đề tôi dự đoán. 27 00:01:16,590 --> 00:01:18,650 >> Làm cho scanf-1. 28 00:01:18,650 --> 00:01:20,960 ./scanf-1. 29 00:01:20,960 --> 00:01:21,830 Chuỗi xin vui lòng. 30 00:01:21,830 --> 00:01:25,540 Hãy cung cấp một cái gì đó như "xin chào". "Cảm ơn các null." Hmm, đó không phải là 31 00:01:25,540 --> 00:01:26,750 những gì tôi mong đợi. 32 00:01:26,750 --> 00:01:28,240 Vì vậy, những gì đang xảy ra ở đây? 33 00:01:28,240 --> 00:01:32,040 >> Vâng, nó quay ra bởi vì chúng tôi tuyên bố như là một ngôi sao char nhưng chúng tôi đã không 34 00:01:32,040 --> 00:01:36,120 thực sự được lưu trữ trong s địa chỉ của một đoạn thực tế của bộ nhớ, scanf không 35 00:01:36,120 --> 00:01:38,940 có nơi nào để đưa chuỗi mà người dùng đánh máy in 36 00:01:38,940 --> 00:01:42,510 Thật vậy, nếu người dùng là đến nay gõ một chuỗi dài hơn nhiều so với "hello" 37 00:01:42,510 --> 00:01:46,780 Ví dụ một vài dòng văn bản hoặc một số đoạn văn bản, nó khá 38 00:01:46,780 --> 00:01:50,280 có thể là chúng ta có thể tạo ra một cái gọi là lỗi phân khúc. 39 00:01:50,280 --> 00:01:53,570 >> Vì scanf sẽ không biết rằng Tôi đã không thực sự đặt một địa chỉ 40 00:01:53,570 --> 00:01:54,610 bên trong của s. 41 00:01:54,610 --> 00:01:58,000 Thay vào đó, nó sẽ nhìn thấy một số giá trị trong s, một số mô hình của các bit mà có thể 42 00:01:58,000 --> 00:02:00,910 rất tốt là một giá trị rác, có một cách ngẫu nhiên. 43 00:02:00,910 --> 00:02:04,600 Và scanf vẫn sẽ cố gắng viết chuỗi sử dụng địa chỉ đó, 44 00:02:04,600 --> 00:02:08,789 ngay cả khi nó là một giá trị rác, mà thực sự có thể gây ra một vụ tai nạn. 45 00:02:08,789 --> 00:02:10,130 >> Vậy làm thế nào chúng ta sẽ sửa lỗi này? 46 00:02:10,130 --> 00:02:12,523