Dynamischer String-Builder
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 59 von 61.
Aufgabe
EinfachLassen Sie uns einen StringBuilder bauen — einen dynamischen String-Container, der automatisch wächst, wenn Sie Text anhängen. Dies ist ein praktisches Hilfsmittel, das dynamische Speicherverwaltung mit den OOP-Mustern kombiniert, die Sie in diesem Kurs gemeistert haben.
Sie werden Ihren Code auf drei Dateien verteilen:
stringbuilder.h: Deklarieren Sie dieStringBuilder-Struktur mit drei Elementen: einemchar*-Puffer, einemsize_tfür die aktuelle Länge und einemsize_tfür die Gesamtkapazität. Deklarieren Sie Funktionsprototypen zum Erstellen eines StringBuilder, zum Anhängen von Text, zum Abrufen des fertigen Strings und zum Freigeben des Speichers. Include-Guards sind unerlässlich.stringbuilder.c: Implementieren Sie Ihr StringBuilder-System:create_stringbuilder— alloziert 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— nimmt einen StringBuilder-Pointer und einen anzuhängenden String entgegen. Berechnen Sie die neue erforderliche Länge. Wenn diese die Kapazität überschreitet, verdoppeln Sie die Kapazität (wiederholt, falls erforderlich) und verwenden Sierealloc, um den Puffer zu vergrößern. Verketten Sie dann den neuen Text mitstrcat.get_string— gibt einen Pointer auf den internen Puffer zurück (Nur-Lese-Zugriff).free_stringbuilder— gibt zuerst den Puffer frei, dann die StringBuilder-Struktur selbst.
main.c: Lesen Sie eine Ganzzahl ein, die angibt, wie viele Strings angehängt werden sollen. Lesen Sie dann jeden String mitfgetsein und hängen Sie ihn an Ihren StringBuilder an. Nachdem alle Strings hinzugefügt wurden, geben Sie den vollständig zusammengesetzten String mitget_stringaus. Geben Sie abschließend den StringBuilder frei.
Zwei Schlüsselfunktionen, die in dieser Challenge verwendet werden:
realloc(ptr, new_size)— ändert die Größe eines zuvor allozierten Speicherblocks. Sie nimmt einen Pointer auf den bestehenden Block und die neue gewünschte Größe in Bytes entgegen und gibt einen Pointer auf den (möglicherweise verschobenen) in der Größe geänderten Block zurück. Verwenden Sie sie inappend, wenn der Puffer wachsen muss:sb->buffer = (char*)realloc(sb->buffer, sb->capacity);fgets(buffer, size, stream)— liest eine Textzeile aus einem Eingabestrom in ein Zeichen-Array, wobei gestoppt wird, wenn ein Zeilenumbruch erreicht ist odersize - 1Zeichen gelesen wurden. Das Zeilenumbruchzeichen bleibt im Puffer erhalten, daher müssen Sie es manuell entfernen. Verwenden Sie es inmain.c, um jeden Eingabestring zu lesen:fgets(line, sizeof(line), stdin);
Um den abschließenden Zeilenumbruch zu entfernen: Prüfen Sie, ob das letzte Zeichen'\n'ist, und ersetzen Sie es durch'\0'.
Ihr Programm erhält:
- Die Anzahl der anzuhängenden Strings
- Jeden String in einer separaten Zeile
Beispielhafte Ausgabe, wenn die Eingaben 3, dann Hello, , World sind:
Hello WorldBeispielhafte Ausgabe, wenn die Eingaben 4, dann C, is, a, great language! sind:
C is a great language!Beispielhafte Ausgabe, wenn die Eingaben 1, dann SingleString sind:
SingleStringDenken Sie daran, das Feld length nach jeder Append-Operation zu aktualisieren. Wenn Sie prüfen, ob eine Reallokation erforderlich ist, berücksichtigen Sie den Null-Terminator — der Puffer benötigt Platz für length + new_text_length + 1 Bytes. Verwenden Sie strlen aus <string.h>, um Stringlängen zu messen. Rufen Sie außerdem getchar() nach scanf in main.c auf, um den verbleibenden Zeilenumbruch zu konsumieren, bevor Sie Strings mit fgets lesen.
Probier es selbst
#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"
int main() {
int n;
scanf("%d", &n);
getchar(); // Zeilenumbruch nach der Zahl verarbeiten
// TODO: Erstelle einen StringBuilder mit create_stringbuilder()
// TODO: Lies n Strings ein und hänge jeden an den StringBuilder an
// Hint: Verwende fgets oder Ähnliches, um jede Zeile zu lesen
// Denke daran, das Zeilenumbruchzeichen von fgets zu behandeln, falls du es verwendest
// TODO: Gib den vollständigen zusammengesetzten String mit get_string() aus
// TODO: Gib den StringBuilder mit free_stringbuilder() frei
return 0;
}
Alle Lektionen in Object Oriented Programming
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-Implementierung