1 00:00:00,000 --> 00:00:00,180 2 00:00:00,180 --> 00:00:02,920 >> 1 głośnik: Napiszmy program, który Pobiera ciąg od użytkownika bez 3 00:00:02,920 --> 00:00:05,700 używając CS50 biblioteki funkcjonować GetString. 4 00:00:05,700 --> 00:00:08,720 Aby to zrobić, będziemy już używać scanf, funkcja GetString 5 00:00:08,720 --> 00:00:10,950 funkcja nie używa pod wyciągiem. 6 00:00:10,950 --> 00:00:13,780 Ale mam zamiar to zrobić celowo w sposób buggy. 7 00:00:13,780 --> 00:00:17,230 Mam zamiar zrobić w taki sposób, że myślę, że byłoby dobrze, ale okazuje się, że 8 00:00:17,230 --> 00:00:19,380 moje założenie będzie całkiem, całkiem błędna. 9 00:00:19,380 --> 00:00:20,800 I rzeczywiście bardzo niebezpieczne. 10 00:00:20,800 --> 00:00:24,750 Ponieważ błędy takie jak ten mam zamiar Marka może być wykorzystana przez przeciwników 11 00:00:24,750 --> 00:00:28,870 takie, że urządzenie lub program może zostać przejęte potencjalnie. 12 00:00:28,870 --> 00:00:30,200 >> Zacznijmy w następujący sposób. 13 00:00:30,200 --> 00:00:33,540 Zacznijmy deklarujemy ciąg, znanym teraz jako gwiazda char, 14 00:00:33,540 --> 00:00:34,750 i nazywają to s. 15 00:00:34,750 --> 00:00:39,400 Pozwala obok pyta użytkownika o ciąg, jak z "ciąg proszę." I 16 00:00:39,400 --> 00:00:44,250 niech teraz uzyskać ciąg od użytkownika przy użyciu scanf, cytatu, "% s". W 17 00:00:44,250 --> 00:00:47,760 Innymi słowy, załóżmy, że my informujemy scanf Czy rzeczywiście spodziewać się ciąg 18 00:00:47,760 --> 00:00:48,630 od użytkownika. 19 00:00:48,630 --> 00:00:50,810 >> Ale teraz musimy powiedzieć scanf jedna rzecz - 20 00:00:50,810 --> 00:00:53,350 gdzie umieścić napis, że Użytkownik zapewnia. 21 00:00:53,350 --> 00:00:57,840 Cóż, mam zamiar po prostu zacząć z przecinkiem s, określając, że chciałbym 22 00:00:57,840 --> 00:00:59,320 scanf umieścić ciąg tam. 23 00:00:59,320 --> 00:01:04,818 Jestem następny zamiar wydrukować coś jak printf "thanks for% s 24 00:01:04,818 --> 00:01:10,670 odwrotny ukośnik n przecinek. "I jak zawsze, jestem przejdzie w ciągu, s.. 25 00:01:10,670 --> 00:01:14,920 Teraz możemy zapisać, skompilować i uruchomić ten Program, i zobacz, czy nie możemy wywoływać 26 00:01:14,920 --> 00:01:16,590 Problem przewidziałem. 27 00:01:16,590 --> 00:01:18,650 >> Dodać scanf-1. 28 00:01:18,650 --> 00:01:20,960 ./scanf-1. 29 00:01:20,960 --> 00:01:21,830 Ciąg proszę. 30 00:01:21,830 --> 00:01:25,540 Miejmy dostarczyć coś, "hello". "Dzięki za null." Hmm, to nie jest 31 00:01:25,540 --> 00:01:26,750 czego się spodziewałem. 32 00:01:26,750 --> 00:01:28,240 Więc co tu się dzieje? 33 00:01:28,240 --> 00:01:32,040 >> Cóż, okazuje się, dlatego, że zadeklarowane a jako gwiazda char ale nie 34 00:01:32,040 --> 00:01:36,120 faktycznie przechowywane w s adres Rzeczywisty fragment pamięci, scanf nie 35 00:01:36,120 --> 00:01:38,940 nigdzie umieścić napis że użytkownik wpisze w. 36 00:01:38,940 --> 00:01:42,510 W rzeczywistości, jeżeli użytkownik był do tej pory wpisać znacznie dłuższy ciąg niż "hello" 37 00:01:42,510 --> 00:01:46,780 na przykład kilka linii tekstu lub kilka akapitów tekstu, jest dość 38 00:01:46,780 --> 00:01:50,280 możliwe, że możemy wywołać tzw błędu segmentacji. 39 00:01:50,280 --> 00:01:53,570 >> Bo scanf nie będzie wiedzieć, że Nie faktycznie umieścić adres 40 00:01:53,570 --> 00:01:54,610 wewnątrz s. 41 00:01:54,610 --> 00:01:58,000 Raczej to się zobaczyć jakąś wartość w s, jakiś wzór bitów, które mogą 42 00:01:58,000 --> 00:02:00,910 bardzo dobrze wartość śmieci, nie tylko przez przypadek. 43 00:02:00,910 --> 00:02:04,600 I scanf nadal będzie starał się pisać Ciąg użytkownikowi tego adresu, 44 00:02:04,600 --> 00:02:08,789 Nawet jeśli jest to wartość śmieci, które rzeczywiście może wywołać katastrofę. 45 00:02:08,789 --> 00:02:10,130 >> Więc jak będziemy to naprawić? 46 00:02:10,130 --> 00:02:12,523