動的文字列ビルダー
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 59/61。
チャレンジ
簡単StringBuilderを作成しましょう。これは、テキストを append すると自動的に grow する dynamic な string container です。これは、コース全体を通して習得してきた dynamic memory management と OOP patterns を組み合わせた実用的な utility です。
コードを3つのファイルに分けて整理します。
stringbuilder.h: 3つのメンバーを持つStringBuilderstruct を Declare します。メンバーはchar*buffer、current length 用のsize_t、total capacity 用のsize_tです。StringBuilder の作成、テキストの append、final string の取得、memory の解放を行う Function prototypes を Declare します。Include guards は essential です。stringbuilder.c: StringBuilder system を Implement します。create_stringbuilder: heap 上に StringBuilder を allocated し、buffer を initial capacity 16 bytes で初期化し、length を 0 に設定し、buffer が empty string(null-terminated)として始まることを保証しますappend: StringBuilder pointer と append する string を受け取ります。新しく必要な length を Calculate します。それが capacity を exceeds する場合は、capacity を(必要なら繰り返し)double し、reallocを使って buffer を grow します。その後、strcatを使って新しいテキストを concatenate しますget_string: internal buffer への pointer を返します(read-only access)free_stringbuilder: まず buffer を frees し、その後 StringBuilder struct 自体を frees します
main.c: append する string の数を示す integer を読み取ります。次にfgetsを使って各 string を読み取り、StringBuilder に append します。すべての string を追加した後、get_stringを使って complete assembled string を print します。最後に StringBuilder を free します。
この challenge で使用する2つの key functions:
realloc(ptr, new_size): previously allocated された memory block の size を変更します。既存の block への pointer と、新しく希望する size(bytes 単位)を受け取り、(移動される可能性のある)resized block への pointer を返します。buffer を grow する必要がある場合、appendで使用します。sb->buffer = (char*)realloc(sb->buffer, sb->capacity);fgets(buffer, size, stream): input stream から text の1行を character array に読み込み、newline またはsize - 1characters が読み込まれた時点で停止します。newline character は buffer に保持されるため、手動で strip する必要があります。main.cで各 input string を読み取るために使用します。fgets(line, sizeof(line), stdin);
末尾の newline を strip するには、最後の character が'\n'かどうかを確認し、'\0'に置き換えます。
プログラムは次の内容を受け取ります。
- append する string の数
- 各 string を別々の行に入力
入力が 3、続いて Hello、、World の場合の出力例:
Hello World入力が 4、続いて C、is、a、great language! の場合の出力例:
C is a great language!入力が 1、続いて SingleString の場合の出力例:
SingleString各 append operation の後に length field を update することを忘れないでください。reallocation が必要かどうかを確認するときは、null terminator を考慮してください。buffer には length + new_text_length + 1 bytes 分の space が必要です。string lengths の測定には <string.h> の strlen を使用します。また、fgets で string を読み取る前に残っている newline を consume するため、main.c で scanf の後に getchar() も call してください。
自分で試してみよう
#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"
int main() {
int n;
scanf("%d", &n);
getchar(); // 数値の後の改行を消費する
// TODO: Create a StringBuilder using create_stringbuilder()
// TODO: Read n strings and append each to the StringBuilder
// ヒント: 各行を読み取るには fgets または同様のものを使用してください
// fgets を使用する場合は、fgets からの改行文字を処理することを忘れないでください
// TODO: get_string() を使用して組み立てた完全な文字列を出力する
// TODO: Free the StringBuilder using free_stringbuilder()
return 0;
}
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ