C语言String结构体,模仿Java的String类(一)

本文介绍了如何在C语言中模仿Java的String类,创建一个名为String的结构体,封装字符串处理函数。在cExample项目的util文件夹下,作者创建了my_string.h头文件,定义了结构体并包含了一系列相关方法。文章将逐步解析每个方法的实现和结构体的使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       为cExample项目创建各种工具函数,作为后续代码的依赖,今天我们来仿照java的String类,写一个C语言的String结构体,这个结构体封装了各种针对字符串的使用函数,将这些函数组织和封装到String结构体中,为后续我们处理C语言的字符串打下一个坚实的基础,现在我们来看看头文件时如何编写的。

        首先我们在cExample的util文件夹下创建my_string.h头文件,定义好String结构体,并将各种函数(参考Java的String类)定义在结构体中。如图:

我们先介绍一下my_string.h头文件的内容,源代码如下:

#ifndef MY_STRING_H_INCLUDED
#define MY_STRING_H_INCLUDED

#include <stdbool.h>
#include <string.h>
#include <ctype.h>

struct string_segment;

struct my_string;   // 使用结构体的不完整定义
typedef struct my_string String;  // 定义字符串结构体的类型别名

/**
 * 完整的定义my_string结构体
*/
struct my_string{
    
    int length;   // 字符串的长度, 不包含末尾的\0
    char* value; // 字符串的内容
    
    char (*char_at)(String* thisptr, int index); // 获取指定位置的字符
    int (*index_of)(String* thisptr, char ch); // 获取字符串中第一次出现的指定字符的索引
    int (*last_index_of)(String* thisptr, char ch); // 获取字符串中最后一次出现的指定字符的索引
    int (*index_of_str)(String* thisptr, const char* chptr); // 获取字符串中第一次出现的指定字符的索引
    int (*last_index_of_str)(String* thisptr, const char* chptr); // 获取字符串中最后一次出现的指定字符的索引
    int (*str_count)(String* thisptr, const char* chptr); // 获得指定字符串的在源字符串中的数量
    int* (*str_indexs)(String* thisptr, const char* chptr, int size);

    bool (*is_empty)(String* thisptr); // 判断字符串是否为空
    bool (*equals)(String* thisptr, const char* str); // 判断字符串是否与str相同
    bool (*contains)(String* thisptr, const char* str); // 判断字符串是否包含str
    bool (*starts_with)(String* thisptr, const char* prefix); // 判断字符串是否以prefix开头
    bool (*ends_with)(String* thisptr, const char* suffix); // 判断字符串是否以suffix结尾
    
    struct string_segment* (*split_by)(String* thisptr, const char* chptr); // 字符串分割
    
    /**
     * 创建一个新的字符串结构体,将字符串内容和长度保存到结构体中
     * 在堆空间中开辟存储空间,使其刚好保存字符串的内容,并在末尾添加一个\0
     * str中\0后边的部分不会被保存到结构体中
    */
    void (*new_string)(String* thisptr, const char* str);
    
    String* (*substring)(String* thisptr, int start, int end); // 获取子字符串
    String* (*substring_from)(String* thisptr, int start); // 获取从start开始的子字符串
    String* (*substring_to)(String* thisptr, int end); // 获取从0到end结束的子字符串
    String* (*to_lower)(String* thisptr); // 转换字符串为小写
    String* (*to_upper)(String* thisptr); // 转换字符串为大写

    String* (*concat)(String* thisptr, const char* str); // 连接字符串
    
    void (*trim_string)(String* thisptr); // 去除字符串两端的空白字符
    const char* (*to_string)(String* thisptr); // 打印字符串内容到标准输出

    int (*count_alnum)(String* thisptr); // 计算字符串中字母和数字的数量
    int (*count_alpha)(String* thisptr); // 计算字符串中字母的数量
    int (*count_digit)(String* thisptr); // 计算字符串中数字的数量
    int (*count_space)(String* thisptr); // 计算字符串中空格的数量
    
};

// 字符串分段结构体,用于记录分割后的字符串数组
struct string_segment{
    String** strptr; 
    int count;   // 字符串数组的长度
};

/**
 * 构建一个空的字符串结构体
 */
String* build_empty_string(void);

/**
 * 创建一个字符串结构体,将字符串内容和长度保存到结构体中
 * 在堆空间中开辟存储空间,使其刚好保存字符串的内容,并在末尾添加一个\0
 * str中\0后边的部分不会被保存到结构体中
 * 
 * @param str 字符串内容
 * @return 字符串结构体指针
 */
String* build_string(const char* str); // 构建字符串
/**
 * 释放字符串结构体
 * @param str 字符串结构体指针
 */
void free_string(String* str); // 释放字符串

/**
 * 判断字符串是否为空串
 * str为NULL返回false str的长度为0以及只包含\0也返回false
 * @param str 字符串结构体指针
 * @return 字符串是否为空 true:空串 false:非空串
 */
bool is_empty(String* str); // 判断字符串是否为空

/**
 * 获得指定位置的字符
 * @param thisptr 字符串结构体指针
 * @param index 位置索引
 * @return 指定索引的字符,如果索引越界,返回\0
 */
char char_at(String* thisptr, int index);

/**
 * 获取字符串中第一次出现的指定字符的索引
 * 
 * @param thisptr 字符串结构体指针
 * @param ch 指定字符
 * @return 第一次出现的索引,如果没有找到,返回-1
 */
int index_of(String* thisptr, char ch);

/**
 * 获取字符串中最后一次出现的指定字符的索引
 * 
 * @param thisptr 字符串结构体指针
 * @param ch 指定字符
 * @return 最后一次出现的索引,如果没有找到,返回-1
 */
int last_index_of(String* thisptr, char ch);

/**
 * 获取字符串中第一次出现的指定字符串的索引
 * 
 * @param thisptr 字符串结构体指针
 * @param chptr 指定字符串
 * @return 第一次出现的索引,如果thisptr为NULL或chptr为NULL没有找到,返回-1
 */
int index_of_str(String* thisptr, const char* chptr); 


/**
 * 判断字符串是否以prefix开头
 * 
 * @param thisptr 字符串结构体指针
 * @param prefix 前缀字符串
 * @return 字符串是否以prefix开头 true:是 false:否
*/
bool starts_with(String* thisptr, const char* prefix);

/**
 * 判断字符串是否以suffix结尾
 * 
 * @param thisptr 字符串结构体指针
 * @param suffix 后缀字符串
 * @return 字符串是否以suffix结尾 true:是 false:否
 */
bool ends_with(String* thisptr, const char* suffix);


/**
 * 判断字符串是否和str相同,每个字符都一样
 * @param thisptr 字符串结构体指针
 * @param str 字符串指针
 * @return 字符串是否相同 true:相同 false:不同
 */
bool equals(String* thisptr, const char* str);

/**
 *  获取字符串中从start到end的子串
 * 
 * @param thisptr 字符串结构体指针
 * @param start 子串的起始位置 包含
 * @param end 子串的结束位置 不包含
 * @return 子串的字符串结构体指针
 */
String* substring(String* thisptr, int start, int end);

/**
 * 获取从start开始到字符串末尾的子串
 * 
 * @param thisptr 字符串结构体指针
 * @param start 子串的起始位置 包含
 * @return 子串的字符串结构体指针
 */
String* substring_from(String* thisptr, int start); // 获取从start开始的子字符串

/**
 * 获取从0到end结束的子串
 * 
 * @param thisptr 字符串结构体指针
 * @param end 子串的结束位置 不包含
 * @return 子串的字符串结构体指针
 */
String* substring_to(String* thisptr, int end); // 获取从0到end结束的子字符串

/**
 * 判断字符串是否包含str
 * 
 * @param thisptr 字符串结构体指针
 * @param str 字符串指针 是否被包含的字符串
 * 
 * @return 字符串是否包含str true:包含 false:不包含
 *  
 */
bool contains(String* thisptr, const char* str);

/**
 * 打印字符串内容
 * @param thisptr 字符串结构体指针
 */
const char* to_string(String* thisptr); 

/**
 * 将字符串转换为小写
 * @param thisptr 字符串结构体指针
 * @return 转换后的字符串结构体指针
 */
String* to_lower(String* thisptr); // 转换字符串为小写

/**
 * 将字符串转换为大写
 * @param thisptr 字符串结构体指针
 * @return 转换后的字符串结构体指针
 */
String* to_upper(String* thisptr); // 转换字符串为大写

/**
 * 连接字符串
 * @param thisptr 字符串结构体指针
 * @param str 字符串指针 要连接的字符串
 * @return 连接后的字符串结构体指针
 */
String* concat(String* thisptr, const char* str); // 连接字符串

/**
 * 去除字符串两端的空白字符
 * @param thisptr 字符串结构体指针
 * 
 */
void trim_string(String* thisptr); // 去除字符串两端的空白字符

/**
 * 计算chptr在thisptr中出现的次数
 * @param thisptr 字符串结构体指针
 * @return 出现的次数
 */
int str_count(String* thisptr, const char* chptr);

/**
 * 返回chptr在thisptr中出现的各索引
 * @param thisptr 字符串结构体指针
 * @param chptr 子串指针
 * @param size 子串数量
 * 
 */
int* str_indexs(String* thisptr, const char* chptr, int size);

/**
 * 将str的内容复制到thisptr中,源字符串的内容释放掉
 * 
 * @param thisptr 字符串结构体指针
 */
void new_string(String* thisptr, const char* str);

/**
 * 计算字符串中字母和数字的数量
 * @param thisptr 字符串结构体指针
 * @return 字母和数字的数量
 */
int count_alnum(String* thisptr); // 计算字符串中字母和数字的数量

/**
 * 计算字符串中字母的数量
 * @param thisptr 字符串结构体指针
 * @return 字母的数量
 */
int count_alpha(String* thisptr); // 计算字符串中字母的数量

/**
 * 计算字符串中数字的数量
 * @param thisptr 字符串结构体指针
 * @return 数字的数量
 */
int count_digit(String* thisptr); // 计算字符串中数字的数量
int count_space(String* thisptr); // 计算字符串中空格的数量

/**
 * 找到最后一次出现的子串的索引
 * 
 * @param thisptr 字符串结构体指针
 * @param chptr 子串指针
 * @return 最后一次出现的索引,如果没有找到,返回-1
 * 
 */
int last_index_of_str(String* thisptr, const char* chptr);

/**
 * 计算字符串的长度,不包含结束符'\0'
 * @param str 字符串指针
 * @return 字符串的长度
 */
int string_length(const char* str);

/**
 * 分割字符串
 * 
 * @param thisptr 字符串结构体指针
 * @param chptr 分割字符
 * @return string_segment结构体指针
 */
struct string_segment* split_by(String* thisptr, const char* chptr);

/**
 * 按chptr分割后的字符串数量
 * 
 * @param thisptr 字符串结构体指针
 * @param chptr 分割字符
 * @return 分割后的字符串数量
 */
int size_of_split_by(String* thisptr, const char* chptr);

#endif // MY_STRING_H_INCLUDED

后续我们将详细介绍每一个方法的具体实现,以及如何使用String结构体。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会C、Java多种开发语言的金哥

您的鼓励是我创作的动力源泉!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值