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] [Harvard University] 3 00:00:04,220 --> 00:00:07,260 [Dies ist CS50. CS50.TV] 4 00:00:07,260 --> 00:00:11,510 Das CS50-Bibliothek ist ein hilfreiches Werkzeug, dass wir auf dem Gerät installiert 5 00:00:11,510 --> 00:00:15,870 um es einfacher für Sie, um Programme zu schreiben, dass Benutzer auffordern für die Eingabe. 6 00:00:15,870 --> 00:00:21,670 In diesem Video werden wir ziehen den Vorhang zurück und schauen, was genau in der CS50-Bibliothek. 7 00:00:21,670 --> 00:00:25,520 >> In dem Video auf C-Bibliotheken, wir reden darüber, wie Sie # include Header-Dateien 8 00:00:25,520 --> 00:00:27,570 der Bibliothek in Ihrem Quellcode, 9 00:00:27,570 --> 00:00:31,150 und dann verknüpfen Sie mit einer binären Library-Datei während der Verknüpfung Phase 10 00:00:31,150 --> 00:00:33,140 der Kompilierung. 11 00:00:33,140 --> 00:00:36,440 Die Header-Dateien angeben, die Schnittstelle der Bibliothek. 12 00:00:36,440 --> 00:00:41,280 Das heißt, sie ausführlich alle Ressourcen, die die Bibliothek für Sie zu nutzen, 13 00:00:41,280 --> 00:00:45,250 wie Funktions-Deklarationen, Konstanten und Datentypen. 14 00:00:45,250 --> 00:00:48,890 Die binäre Library-Datei enthält die Implementierung der Bibliothek, 15 00:00:48,890 --> 00:00:54,580 welches aus der Bibliothek Header-Dateien und die Bibliothek. c Quellcode-Dateien kompiliert. 16 00:00:54,580 --> 00:00:59,820 >> Die binäre Library-Datei ist nicht sehr interessant zu sehen, da es ist gut, in binär. 17 00:00:59,820 --> 00:01:03,300 Also, lassen Sie uns einen Blick auf die Header-Dateien für die Bibliothek statt. 18 00:01:03,300 --> 00:01:07,710 In diesem Fall gibt es nur eine Header-Datei namens cs50.h. 19 00:01:07,710 --> 00:01:11,040 Wir haben es in der Benutzer installiert include 20 00:01:11,040 --> 00:01:15,150 Zusammen mit den anderen System-Bibliotheken 'Header-Dateien. 21 00:01:15,150 --> 00:01:21,530 >> Eines der ersten Dinge, die Sie bemerken ist, dass cs50.h # enthält Header-Dateien aus anderen Bibliotheken - 22 00:01:21,530 --> 00:01:25,670 float, Grenzen, Standard bool und Standard-lib. 23 00:01:25,670 --> 00:01:28,800 Auch nach dem Prinzip der nicht das Rad neu erfinden, 24 00:01:28,800 --> 00:01:33,490 wir haben die CS0 Bibliothek mit Werkzeugen, die anderen zur Verfügung gestellt für uns gebaut. 25 00:01:33,490 --> 00:01:38,690 >> Das nächste, was Sie in der Bibliothek zu sehen müssen, ist, dass wir einen neuen Typ namens definieren "string". 26 00:01:38,690 --> 00:01:42,330 Diese Linie wirklich nur erstellt einen Alias ​​für den char *-Typ, 27 00:01:42,330 --> 00:01:46,000 so dass es nicht magisch verleihen dem neuen String-Typ mit Attributen 28 00:01:46,000 --> 00:01:49,650 häufig mit String-Objekten in anderen Sprachen verbunden sind, 29 00:01:49,650 --> 00:01:50,850 wie Länge. 30 00:01:50,850 --> 00:01:55,180 Der Grund warum wir dies getan haben ist es, neue Programmierer aus den blutigen Details abschirmen 31 00:01:55,180 --> 00:01:57,580 von Zeigern, bis sie bereit sind. 32 00:01:57,580 --> 00:02:00,130 >> Der nächste Teil der Header-Datei ist die Erklärung der Funktionen 33 00:02:00,130 --> 00:02:04,410 dass der CS50-Bibliothek bietet zusammen mit einer Dokumentation. 34 00:02:04,410 --> 00:02:06,940 Beachten Sie die Detailstufe in den Kommentaren hier. 35 00:02:06,940 --> 00:02:10,560 Das ist super wichtig, damit Menschen wissen, wie diese Funktionen nutzen. 36 00:02:10,560 --> 00:02:19,150 Wir erklären, die wiederum funktioniert, um den Benutzer-oder Rückgabebelehrung Zeichen-, Doppel-, Schwimmern, ints aufgefordert, 37 00:02:19,150 --> 00:02:24,160 lange sehnt, und Streicher, mit unseren eigenen String-Typ. 38 00:02:24,160 --> 00:02:26,260 Nach dem Prinzip des Information Hiding, 39 00:02:26,260 --> 00:02:31,640 . haben wir unsere Definition in einem separaten c Umsetzung Datei ablegen - cs50.c-- 40 00:02:31,640 --> 00:02:35,110 befindet sich in der Benutzer-Quellverzeichnis. 41 00:02:35,110 --> 00:02:38,040 Wir haben diese Datei zur Verfügung gestellt, so dass Sie einen Blick darauf werfen können, 42 00:02:38,040 --> 00:02:41,490 daraus lernen, und kompilieren Sie es auf verschiedenen Maschinen, wenn Sie es wünschen, 43 00:02:41,490 --> 00:02:45,510 obwohl wir denken, es ist besser, um das Gerät in dieser Klasse arbeiten. 44 00:02:45,510 --> 00:02:47,580 Wie auch immer, lassen Sie uns einen Blick auf sie jetzt. 45 00:02:49,020 --> 00:02:54,620 >> Die Funktionen GetChar GetDouble, GetFloat, GetInt und GetLongLong 46 00:02:54,620 --> 00:02:58,160 sind alle auf der Oberseite des GetString-Funktion eingebaut. 47 00:02:58,160 --> 00:03:01,510 Es stellt sich heraus, dass sie alle folgen im Wesentlichen dem gleichen Muster. 48 00:03:01,510 --> 00:03:04,870 Sie verwenden eine while-Schleife, um den Benutzer für eine Zeile einer Eingabe auffordern. 49 00:03:04,870 --> 00:03:08,430 Sie kehren einen besonderen Wert, wenn die Eingaben des Benutzers eine leere Zeile. 50 00:03:08,430 --> 00:03:11,750 Sie versuchen, die Eingabe des Benutzers, wie des entsprechenden Typs analysieren, 51 00:03:11,750 --> 00:03:15,010 sei es ein char, ein Doppelzimmer, ein Schwimmer, etc. 52 00:03:15,010 --> 00:03:18,710 Und dann sind sie entweder wieder das Ergebnis, wenn die Eingabe erfolgreich analysiert wurde 53 00:03:18,710 --> 00:03:21,330 Erneut auffordern oder sie den Benutzer. 54 00:03:21,330 --> 00:03:24,230 >> Auf einem hohen Niveau, es gibt nichts wirklich schwierig hier. 55 00:03:24,230 --> 00:03:28,760 Vielleicht schriftlichen ähnlich strukturierten Code haben sich in der Vergangenheit. 56 00:03:28,760 --> 00:03:34,720 Vielleicht die kryptische wirkende Teil ist der Anruf, der sscanf die Eingabe des Benutzers analysiert. 57 00:03:34,720 --> 00:03:38,160 Sscanf ist Teil des Eingangs-Format Konvertierung Familie. 58 00:03:38,160 --> 00:03:42,300 Er lebt in Standard io.h, und seine Aufgabe ist es, einen C-String parsen, 59 00:03:42,300 --> 00:03:46,520 nach einem bestimmten Format und speichert die parse Ergebnisse in variable 60 00:03:46,520 --> 00:03:48,720 vorgesehen durch den Anrufer. 61 00:03:48,720 --> 00:03:53,570 Da die Eingangs-Format-Konvertierung Funktionen sind sehr nützlich, weithin verwendete Funktionen 62 00:03:53,570 --> 00:03:56,160 die nicht sind super intuitive zunächst 63 00:03:56,160 --> 00:03:58,300 gehen wir darüber, wie sscanf funktioniert. 64 00:03:58,300 --> 00:04:03,330 >> Das erste Argument sscanf ist ein char * - ein Zeiger auf ein Zeichen. 65 00:04:03,330 --> 00:04:05,150 Für die Funktion nicht richtig arbeiten, 66 00:04:05,150 --> 00:04:08,340 dieser Charakter sollte das erste Zeichen eines C-String sein, 67 00:04:08,340 --> 00:04:12,270 beendet mit dem null \ 0 Zeichen. 68 00:04:12,270 --> 00:04:15,120 Dies ist die Zeichenfolge zu analysieren 69 00:04:15,120 --> 00:04:18,269 Das zweite Argument sscanf ist eine Format-String, 70 00:04:18,269 --> 00:04:20,839 typischerweise in als String Konstante übergeben, 71 00:04:20,839 --> 00:04:24,040 und man könnte einen String, wie dies vor, wenn Sie printf gesehen haben. 72 00:04:24,040 --> 00:04:28,650 Ein Prozentzeichen im Format-String zeigt eine Konvertierungsspezifizierer. 73 00:04:28,650 --> 00:04:30,850 Der Charakter unmittelbar nach einem Prozent-Zeichen, 74 00:04:30,850 --> 00:04:35,430 zeigt das C-Typ, die wir wollen sscanf zu konvertieren. 75 00:04:35,430 --> 00:04:40,090 In GetInt, sehen Sie, dass es eine% d und% c. 76 00:04:40,090 --> 00:04:48,690 Dies bedeutet, dass sscanf wird in eine Dezimalzahl int versuchen - das% d - und char - das% c. 77 00:04:48,690 --> 00:04:51,510 Für jede Konvertierung im Format-String, 78 00:04:51,510 --> 00:04:56,620 sscanf erwartet eine entsprechende Argument später in die Liste der Argumente. 79 00:04:56,620 --> 00:05:00,850 Das Argument muss zu einer entsprechend typisierte Speicherort verweisen 80 00:05:00,850 --> 00:05:04,000 bei dem zum Speichern des Ergebnisses der Umwandlung. 81 00:05:04,000 --> 00:05:08,910 >> Der typische Weg dies zu tun ist, um eine Variable auf dem Stack zu erstellen, bevor der sscanf Anruf 82 00:05:08,910 --> 00:05:11,440 für jedes Element, das Sie aus der Zeichenfolge zu analysieren 83 00:05:11,440 --> 00:05:15,520 und verwenden Sie dann die Adresse Betreiber - das kaufmännische - auf Zeiger übergeben 84 00:05:15,520 --> 00:05:19,100 auf diese Variablen in die sscanf Anruf. 85 00:05:19,100 --> 00:05:22,720 Sie können sehen, dass in GetInt wir genau dies tun. 86 00:05:22,720 --> 00:05:28,240 Kurz vor dem sscanf Anruf, erklären wir einen int namens n und ein char Anruf c auf dem Stack, 87 00:05:28,240 --> 00:05:32,340 und wir geben Hinweise, um sie in die sscanf Anruf. 88 00:05:32,340 --> 00:05:35,800 Setzt man diese Variablen auf dem Stack wird über den Weltraum zugeordnet bevorzugt 89 00:05:35,800 --> 00:05:39,350 auf dem Heap mit malloc, da man den Overhead des malloc Aufruf zu vermeiden, 90 00:05:39,350 --> 00:05:43,060 und Sie brauchen sich keine Gedanken über undichte Speicher kümmern. 91 00:05:43,060 --> 00:05:47,280 Zeichen, die nicht von einem Prozent-Zeichen vorangestellt keine Aufforderung Konvertierung. 92 00:05:47,280 --> 00:05:50,380 Vielmehr nur auf die Format-Spezifikation hinzuzufügen. 93 00:05:50,380 --> 00:05:56,500 >> Zum Beispiel, wenn das Format innerhalb GetInt waren% d stattdessen 94 00:05:56,500 --> 00:05:59,800 sscanf würde für das Schreiben einer durch einen int gefolgt aussehen, 95 00:05:59,800 --> 00:06:04,360 und während es versuchen würde, die int konvertieren, wäre es nichts anderes tun, mit der eine. 96 00:06:04,360 --> 00:06:07,440 Die einzige Ausnahme ist Leerzeichen. 97 00:06:07,440 --> 00:06:11,030 Leerzeichen im Formatstring entspricht jede Menge whitespace - 98 00:06:11,030 --> 00:06:12,890 sogar überhaupt keine. 99 00:06:12,890 --> 00:06:18,100 Also, das ist, warum der Kommentar erwähnt, eventuell mit führenden und / oder nachfolgende Leerzeichen. 100 00:06:18,100 --> 00:06:22,910 So wird es an dieser Stelle sieht aus wie unser sscanf Anruf versuchen, die Eingabe des Benutzers String parsen 101 00:06:22,910 --> 00:06:25,380 indem für mögliche führenden Leerzeichen, 102 00:06:25,380 --> 00:06:29,300 gefolgt von einer int, umgewandelt und wird in der Variablen n int gespeichert werden 103 00:06:29,300 --> 00:06:33,090 gefolgt von einer gewissen Menge von Leerzeichen, gefolgt von einem Zeichen 104 00:06:33,090 --> 00:06:35,810 gespeichert in der char-Variable c. 105 00:06:35,810 --> 00:06:37,790 >> Was ist mit dem Rückgabewert? 106 00:06:37,790 --> 00:06:41,560 Sscanf wird die Eingabezeile von Anfang analysieren zu beenden, 107 00:06:41,560 --> 00:06:44,860 stoppt, wenn er das Ende erreicht oder wenn ein Zeichen in der Eingabe 108 00:06:44,860 --> 00:06:49,320 nicht mit einem Format Zeichen oder, wenn es nicht eine Bekehrung. 109 00:06:49,320 --> 00:06:52,690 Es ist Rückgabewert wird verwendet, um einzelne, wenn es gestoppt. 110 00:06:52,690 --> 00:06:55,670 Wenn sie gestoppt werden, weil sie das Ende der Eingabekette erreicht 111 00:06:55,670 --> 00:07:00,630 bevor Sie irgendwelche Umbauten und wartet, bevor er einen Teil der Format-String übereinstimmen, 112 00:07:00,630 --> 00:07:04,840 dann die spezielle Konstante EOF zurückgegeben. 113 00:07:04,840 --> 00:07:08,200 Andernfalls gibt es die Anzahl der erfolgreichen Conversions, 114 00:07:08,200 --> 00:07:14,380 was könnte 0, 1 oder 2 sein, da wir für zwei Konvertierungen gebeten habe. 115 00:07:14,380 --> 00:07:19,000 In unserem Fall wollen wir sicherstellen, dass die Benutzer in einem int und nur einen int eingegeben. 116 00:07:19,000 --> 00:07:23,370 >> So wollen wir sscanf auf 1 zurück. Sehen Sie, warum? 117 00:07:23,370 --> 00:07:26,850 Wenn sscanf ergab 0, dann werden keine Konvertierungen vorgenommen wurden, 118 00:07:26,850 --> 00:07:31,690 so dass der Benutzer etwas anderes als ein int zu Beginn der Eingabe eingegeben. 119 00:07:31,690 --> 00:07:37,100 Wenn sscanf 2 zurückgibt, dann wird der Benutzer hat richtig geben Sie ihn in zu Beginn des Eingangs, 120 00:07:37,100 --> 00:07:41,390 aber sie dann in einigen Nicht-Leerzeichen eingegeben danach 121 00:07:41,390 --> 00:07:44,940 seit% c Konvertierung erfolgreich. 122 00:07:44,940 --> 00:07:49,570 Wow, das ist ein recht langwieriger Erklärung für ein Funktionsaufruf. 123 00:07:49,570 --> 00:07:53,460 Jedenfalls, wenn Sie mehr Informationen über sscanf und seine Geschwister, 124 00:07:53,460 --> 00:07:57,130 Besuche die man pages, Google, oder beides. 125 00:07:57,130 --> 00:07:58,780 Es gibt viele Format-String-Optionen, 126 00:07:58,780 --> 00:08:03,830 und diese können Sie sparen eine Menge Handarbeit, wenn sie versuchen, um Zeichenfolgen in C analysieren 127 00:08:03,830 --> 00:08:07,180 >> Die letzte Funktion in der Bibliothek zu betrachten ist GetString. 128 00:08:07,180 --> 00:08:10,310 Es stellt sich heraus, dass GetString eine heikle Funktion nicht richtig schreiben kann, 129 00:08:10,310 --> 00:08:14,290 obwohl es scheint, wie so eine einfache, gemeinsame Aufgabe. 130 00:08:14,290 --> 00:08:16,170 Warum ist das der Fall? 131 00:08:16,170 --> 00:08:21,380 Nun, lasst uns darüber, wie wir gehen, um die Linie zu speichern, dass der Benutzer Typen in. 132 00:08:21,380 --> 00:08:23,880 Da ein String ist eine Folge von Zeichen, 133 00:08:23,880 --> 00:08:26,430 könnten wir wollen es in einem Array zu speichern auf dem Stack, 134 00:08:26,430 --> 00:08:31,250 aber wir müssten wissen, wie lange das Array sein wird, wenn wir es erklären. 135 00:08:31,250 --> 00:08:34,030 Ebenso, wenn wir wollen es auf dem Heap setzen, 136 00:08:34,030 --> 00:08:38,090 müssen wir auf malloc passieren die Anzahl von Bytes wollen wir zu reservieren, 137 00:08:38,090 --> 00:08:39,730 dies ist jedoch nicht möglich. 138 00:08:39,730 --> 00:08:42,760 Wir haben keine Ahnung, wie viele Zeichen der Benutzer eintippen 139 00:08:42,760 --> 00:08:46,590 bevor der Benutzer eigentlich gar geben Sie sie. 140 00:08:46,590 --> 00:08:50,720 >> Eine naive Lösung für dieses Problem ist, einfach behalten einen großen Teil des Raumes, sagen wir, 141 00:08:50,720 --> 00:08:54,540 ein Block von 1000 Zeichen für die Eingabe des Benutzers, 142 00:08:54,540 --> 00:08:57,980 vorausgesetzt, dass der Benutzer niemals in einer Zeichenfolge, dass lange geben. 143 00:08:57,980 --> 00:09:00,810 Dies ist eine schlechte Idee, aus zwei Gründen. 144 00:09:00,810 --> 00:09:05,280 Erstens, vorausgesetzt, dass die Nutzer in der Regel nicht in Strings so lange geben, 145 00:09:05,280 --> 00:09:07,610 Sie könnten verschwenden viel Speicher. 146 00:09:07,610 --> 00:09:10,530 Auf modernen Maschinen, könnte dies nicht ein Problem sein, wenn Sie dies tun 147 00:09:10,530 --> 00:09:13,890 in ein oder zwei isolierte Instanzen, 148 00:09:13,890 --> 00:09:17,630 aber wenn Sie unter Eingabe des Benutzers in einer Schleife und Speicherung zur späteren Verwendung 149 00:09:17,630 --> 00:09:20,870 Sie können schnell saugen eine Tonne des Gedächtnisses. 150 00:09:20,870 --> 00:09:24,450 Außerdem, wenn das Programm Sie schreiben ist für einen kleineren Computer - 151 00:09:24,450 --> 00:09:28,100 ein Gerät wie ein Smartphone oder etwas anderes mit begrenztem Speicher - 152 00:09:28,100 --> 00:09:32,060 Diese Lösung wird Probleme viel schneller verursachen. 153 00:09:32,060 --> 00:09:36,450 Der zweite, aus wichtigem Grund nicht tun, ist, dass es Ihr Programm lässt anfällig 154 00:09:36,450 --> 00:09:39,710 was heißt ein Pufferüberlauf Angriff. 155 00:09:39,710 --> 00:09:45,840 In der Programmierung ist ein Pufferspeicher zum temporären Speichern oder Ausgangsdaten, 156 00:09:45,840 --> 00:09:48,980 die in diesem Fall ist unsere 1000-char-Block. 157 00:09:48,980 --> 00:09:53,370 Ein Pufferüberlauf tritt auf, wenn Daten über das Ende des Blocks geschrieben wird. 158 00:09:53,370 --> 00:09:57,790 >> Zum Beispiel, wenn ein Benutzer tatsächlich Typs in mehr als 1000 Zeichen. 159 00:09:57,790 --> 00:10:01,570 Vielleicht erlebt versehentlich bei der Programmierung mit Arrays. 160 00:10:01,570 --> 00:10:05,620 Wenn Sie ein Array von 10 ints haben, stoppt nichts, was man von dem Versuch zu lesen oder zu schreiben, 161 00:10:05,620 --> 00:10:07,810 der 15. Int. 162 00:10:07,810 --> 00:10:10,000 Es gibt keine Compiler-Warnungen oder Fehler. 163 00:10:10,000 --> 00:10:13,250 Das Programm gerade Schnitzer geradeaus und greift auf den Speicher 164 00:10:13,250 --> 00:10:18,150 wo es denkt, dass die 15. int wird, und dies kann Ihren anderen Variablen überschreiben. 165 00:10:18,150 --> 00:10:22,040 Im schlimmsten Fall können Sie überschreiben einige Ihrer programm-interne 166 00:10:22,040 --> 00:10:26,820 Kontrollmechanismen, um was Ihr Programm tatsächlich auszuführen andere Anweisungen 167 00:10:26,820 --> 00:10:28,340 als beabsichtigt. 168 00:10:28,340 --> 00:10:31,360 >> Nun, es ist nicht üblich, dies versehentlich tun, 169 00:10:31,360 --> 00:10:35,150 aber dies ist ein recht häufiges Technik, die bösen Jungs nutzen, um Programme zu brechen 170 00:10:35,150 --> 00:10:39,080 und legte Schadcode auf fremden Rechnern. 171 00:10:39,080 --> 00:10:42,910 Deshalb können wir nicht einfach unsere naive Lösung. 172 00:10:42,910 --> 00:10:45,590 Wir müssen einen Weg finden, um unsere Programme von verwundbar zu verhindern 173 00:10:45,590 --> 00:10:47,880 zu einem Pufferüberlauf Angriff. 174 00:10:47,880 --> 00:10:51,430 Um dies zu tun, müssen wir sicherstellen, dass unsere Puffer kann wachsen, wie wir lesen 175 00:10:51,430 --> 00:10:53,850 weitere Eingabe von dem Benutzer. 176 00:10:53,850 --> 00:10:57,440 Die Lösung? Wir verwenden einen Heap-Puffer. 177 00:10:57,440 --> 00:10:59,950 Da wir ändern können, indem Sie die Größe des realloc Funktion 178 00:10:59,950 --> 00:11:04,580 und wir verfolgen zwei Zahlen - den Index der nächsten freien Slot im Puffer 179 00:11:04,580 --> 00:11:08,390 und die Länge oder die Kapazität des Puffers. 180 00:11:08,390 --> 00:11:13,210 Wir lesen in chars vom Benutzer ein zu einer Zeit mit dem fgetc Funktion. 181 00:11:13,210 --> 00:11:19,360 Das Argument der fgetc Funktion nimmt - stdin - ist ein Verweis auf den Standard-Input-Strings, 182 00:11:19,360 --> 00:11:23,810 das ist ein Eingangskanal vorgeschalteten, mit dem die Eingabe des Benutzers übertragen wird 183 00:11:23,810 --> 00:11:26,270 von dem Endgerät an das Programm. 184 00:11:26,270 --> 00:11:29,890 >> Immer wenn der Benutzer einen neuen Charakter, überprüfen wir, ob der Index 185 00:11:29,890 --> 00:11:35,810 des nächsten freien Schlitz plus 1 größer ist als die Kapazität des Puffers. 186 00:11:35,810 --> 00:11:39,690 Die +1 kommt, denn wenn der nächste freie Index 5, 187 00:11:39,690 --> 00:11:44,150 dann werden unsere Puffers Länge muss 6 durch 0 Indexierung sein. 188 00:11:44,150 --> 00:11:48,350 Wenn wir aus dem Raum in dem Puffer ausgeführt haben, dann werden wir versuchen, es zu ändern, 189 00:11:48,350 --> 00:11:51,690 verdoppeln, so daß wir unten geschnitten nach der Anzahl der Male, dass wir die Größe 190 00:11:51,690 --> 00:11:54,760 wenn der Benutzer in einem wirklich lange Zeichenfolge eingeben. 191 00:11:54,760 --> 00:11:57,950 Wenn der String bekommen hat zu lange oder wenn wir laufen aus Heap-Speicher, 192 00:11:57,950 --> 00:12:01,350 befreien wir unsere Puffer und null zurück. 193 00:12:01,350 --> 00:12:04,170 >> Schließlich, fügen wir die char in den Puffer. 194 00:12:04,170 --> 00:12:08,200 Sobald der Benutzer ENTER oder kehren, Signaltechnik eine neue Zeile, 195 00:12:08,200 --> 00:12:12,050 oder die spezielle char - Steuerung d -, die ein Ende der Eingangssignale, 196 00:12:12,050 --> 00:12:16,240 machen wir eine Überprüfung, ob der Benutzer tatsächlich in nichts eingegeben überhaupt. 197 00:12:16,240 --> 00:12:18,820 Wenn nicht, kehren wir null. 198 00:12:18,820 --> 00:12:22,280 Ansonsten, weil unser Puffer ist wahrscheinlich größer, als wir brauchen, 199 00:12:22,280 --> 00:12:24,830 im schlimmsten Fall ist es fast doppelt so groß wie wir brauchen 200 00:12:24,830 --> 00:12:27,830 da wir verdoppeln jedes Mal, wenn wir die Größe, 201 00:12:27,830 --> 00:12:31,840 machen wir eine neue Kopie des Strings mit nur die Menge an Speicherplatz, die wir brauchen. 202 00:12:31,840 --> 00:12:34,220 Wir fügen eine zusätzliche 1 der malloc Anruf 203 00:12:34,220 --> 00:12:37,810 so dass es Raum für den besonderen Nullabschlusszeichen Charakter - das \ 0, 204 00:12:37,810 --> 00:12:41,990 die wir anhängen, um die Zeichenfolge, wenn wir in den Rest der Charaktere zu kopieren, 205 00:12:41,990 --> 00:12:45,060 Verwendung strncpy anstelle von strcpy 206 00:12:45,060 --> 00:12:48,830 so dass wir genau angeben, wie viele Zeichen haben wir kopieren wollen. 207 00:12:48,830 --> 00:12:51,690 Strcpy kopiert, bis es eine \ 0 trifft. 208 00:12:51,690 --> 00:12:55,740 Dann befreien wir unser Puffer und gibt das Exemplar des Anrufers. 209 00:12:55,740 --> 00:12:59,840 >> Wer wusste, wie eine einfache anmutende Funktion, so könnte kompliziert sein? 210 00:12:59,840 --> 00:13:02,820 Jetzt wissen Sie, was in der CS50-Bibliothek. 211 00:13:02,820 --> 00:13:06,470 >> Mein Name ist Nate Hardison, und dies ist CS50. 212 00:13:06,470 --> 00:13:08,350 [CS50.TV]