Menu
CoddyTech

动态字符串构建器

本课属于 Coddy C 学习旅程的“面向对象编程”单元。第 59 课,共 61 课。

challenge icon

挑战

简单

让我们来构建一个 StringBuilder:一种动态字符串容器,会在你追加文本时自动扩展。这是一个实用工具,结合了动态内存管理和你在本课程中掌握的面向对象编程模式。

你需要将代码组织到 3 个文件中:

  • stringbuilder.h:声明 StringBuilder 结构体,其中包含 3 个成员:一个 char* 缓冲区、一个表示当前长度的 size_t,以及一个表示总容量的 size_t。声明用于创建 StringBuilder、向其中追加文本、获取最终字符串和释放内存的函数原型。包含保护宏必不可少。
  • stringbuilder.c:实现 StringBuilder 系统:
    • create_stringbuilder:在堆上分配一个 StringBuilder,将缓冲区的初始容量设为 16 字节,将长度设为 0,并确保缓冲区初始为空字符串(以空字符结尾)
    • append:接收一个指向 StringBuilder 的指针和要追加的字符串。计算所需的新长度。如果超过容量,就将容量翻倍(必要时重复执行),并使用 realloc 扩展缓冲区。然后使用 strcat 拼接新文本
    • get_string:返回指向内部缓冲区的指针(只读访问)
    • free_stringbuilder:先释放缓冲区,再释放 StringBuilder 结构体本身
  • main.c:读取一个整数,表示要追加多少个字符串。然后使用 fgets 读取每个字符串,并将其追加到 StringBuilder 中。添加完所有字符串后,使用 get_string 打印拼接好的完整字符串。最后释放 StringBuilder。

本挑战中用到的两个关键函数:

  • realloc(ptr, new_size):调整先前分配的内存块大小。它接收指向现有内存块的指针和以字节为单位的新目标大小,并返回指向调整大小后的内存块(该内存块可能已移动)的指针。当缓冲区需要扩展时,在 append 中使用它:
    sb->buffer = (char*)realloc(sb->buffer, sb->capacity);
  • fgets(buffer, size, stream):从输入流中读取一行文本到字符数组中,遇到换行符或读入 size - 1 个字符时停止。它会将换行符保留在缓冲区中,因此你需要手动移除它。在 main.c 中使用它来读取每个输入字符串:
    fgets(line, sizeof(line), stdin);
    要移除末尾的换行符:检查最后一个字符是否为 '\n',如果是,就将其替换为 '\0'。

程序会收到以下输入:

  1. 要追加的字符串数量
  2. 每个字符串各占一行

输入依次为 3、Hello、空字符串、World 时的输出示例:

Hello World

输入依次为 4、C、is、a、great language! 时的输出示例:

C is a great language!

输入依次为 1、SingleString 时的输出示例:

SingleString

记得在每次追加操作后更新 length 字段。检查是否需要重新分配内存时,要考虑空字符:缓冲区需要有足够空间容纳 length + new_text_length + 1 个字节。使用 <string.h> 中的 strlen 测量字符串长度。还要在 main.c 中的 scanf 后调用 getchar(),以读取并丢弃遗留的换行符,然后再用 fgets 读取字符串。

亲手试试

#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"

int main() {
    int n;
    scanf("%d", &n);
    getchar(); // 读取数字后剩余的换行符
    
    // TODO: 用 create_stringbuilder() 创建一个 StringBuilder
    
    // TODO: 读取 n 个字符串,并逐个追加到 StringBuilder 中
    // 提示:用 fgets 或类似方法读取每一行
    // 如果使用 fgets,记得处理它读入的换行符
    
    // TODO: 用 get_string() 打印拼接完成的字符串
    
    // TODO: 用 free_stringbuilder() 释放 StringBuilder
    
    return 0;
}

面向对象编程中的所有课

自己练习: C 在线编译器