Dynamischer String-Builder
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 59 von 61.
Aufgabe
EinfachErstellen wir einen StringBuilder: einen dynamischen String-Container, der automatisch wächst, wenn du Text anhängst. Dies ist ein praktisches Hilfsprogramm, das dynamische Speicherverwaltung mit den OOP-Mustern verbindet, die du im Laufe dieses Kurses gemeistert hast.
Du wirst deinen Code auf drei Dateien verteilen:
stringbuilder.h: Deklariere die StrukturStringBuildermit drei Mitgliedern: einemchar*-Puffer, einemsize_tfür die aktuelle Länge und einemsize_tfür die gesamte Kapazität. Deklariere Funktionsprototypen zum Erstellen eines StringBuilders, zum Anhängen von Text, zum Abrufen des fertigen Strings und zum Freigeben des Speichers. Include-Guards sind unerlässlich.stringbuilder.c: Implementiere dein StringBuilder-System:create_stringbuilder: reserviert einen StringBuilder auf dem Heap, initialisiert den Puffer mit einer Anfangskapazität von 16 Bytes, setzt die Länge auf 0 und stellt sicher, dass der Puffer als leerer String beginnt (nullterminiert)append: übernimmt einen Zeiger auf einen StringBuilder und einen anzuhängenden String. Berechne die neu erforderliche Länge. Wenn sie die Kapazität überschreitet, verdopple die Kapazität (bei Bedarf wiederholt) und verwenderealloc, um den Puffer zu vergrößern. Verknüpfe anschließend den neuen Text mitstrcat.get_string: gibt einen Zeiger auf den internen Puffer zurück (schreibgeschützter Zugriff)free_stringbuilder: gibt zuerst den Puffer und anschließend die StringBuilder-Struktur selbst frei
main.c: Lies eine Ganzzahl ein, die angibt, wie viele Strings angehängt werden sollen. Lies anschließend jeden String mitfgetsein und hänge ihn an deinen StringBuilder an. Nachdem alle Strings hinzugefügt wurden, gib den vollständig zusammengesetzten String mitget_stringaus. Gib schließlich den StringBuilder frei.
Zwei wichtige Funktionen, die in dieser Aufgabe verwendet werden:
realloc(ptr, new_size): ändert die Größe eines zuvor reservierten Speicherblocks. Die Funktion übernimmt einen Zeiger auf den bestehenden Block und die gewünschte neue Größe in Bytes und gibt einen Zeiger auf den (möglicherweise verschobenen) vergrößerten Speicherblock zurück. Verwende sie inappend, wenn der Puffer vergrößert werden muss:sb->buffer = (char*)realloc(sb->buffer, sb->capacity);fgets(buffer, size, stream): liest eine Textzeile aus einem Eingabestream in ein Zeichen-Array ein und stoppt bei einem Zeilenumbruch oder sobaldsize - 1Zeichen gelesen wurden. Das Zeilenumbruchzeichen bleibt im Puffer erhalten, daher musst du es manuell entfernen. Verwende die Funktion inmain.c, um jeden Eingabestring zu lesen:fgets(line, sizeof(line), stdin);
Um den abschließenden Zeilenumbruch zu entfernen: Prüfe, ob das letzte Zeichen'\n'ist, und ersetze es durch'\0'.
Dein Programm erhält:
- Die Anzahl der anzuhängenden Strings
- Jeden String in einer eigenen Zeile
Beispielausgabe bei den Eingaben 3, danach Hello, , World:
Hello WorldBeispielausgabe bei den Eingaben 4, danach C, is, a, great language!:
C is a great language!Beispielausgabe bei der Eingabe 1, danach SingleString:
SingleStringDenke daran, das Feld length nach jeder Anhängeoperation zu aktualisieren. Berücksichtige bei der Prüfung, ob eine Neuallokation erforderlich ist, den Nullterminator: Der Puffer benötigt Platz für length + new_text_length + 1 Bytes. Verwende strlen aus <string.h>, um Stringlängen zu messen. Rufe in getchar() außerdem scanf nach main.c auf, um den übrig gebliebenen Zeilenumbruch zu verarbeiten, bevor du Strings mit fgets einliest.
Probier es selbst
#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"
int main() {
int n;
scanf("%d", &n);
getchar(); // Zeilenumbruch nach der Zahl konsumieren
// TODO: Create a StringBuilder using create_stringbuilder()
// TODO: Read n strings and append each to the StringBuilder
// Hinweis: Verwende fgets oder Ähnliches, um jede Zeile zu lesen
// Denke daran, das Newline-Zeichen von fgets zu behandeln, falls du es verwendest
// TODO: Gib den vollständigen zusammengesetzten String mit get_string() aus
// TODO: Free the StringBuilder using free_stringbuilder()
return 0;
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-ImplementierungRechteck-ImplementierungPolymorphe VerwendungShape-ContainerÜbe selbstständig: Online-C-Compiler