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

本文介绍了C语言中模仿Java String类的String结构体的几个关键函数,包括to_lower()、to_upper()用于将字符串转换为小写或大写,并在内存分配失败时提供错误信息;concat()函数用于连接两个字符串,以及new_string()函数用于更新字符串内容。这些函数详细阐述了如何在C语言中处理字符串操作和内存管理。
摘要由CSDN通过智能技术生成

本章我们继续介绍String结构体中的函数。

String* to_lower(String* thisptr)函数,将字符串结构体中的value转换成小写,会生成一个新的结构体。

/**
 * 将字符串转换为小写
 * 
 * @param thisptr 字符串结构体指针
 * @return 转换后的字符串结构体指针(新创建了一个String结构体)
 */
String* to_lower(String* thisptr){
    if(thisptr == NULL){
        return build_empty_string(); // 构建空字符串的结构体
    }

    char* newstr = (char*)malloc(thisptr->length + 1); // 在堆上申请内存

    if(newstr == NULL){
        printf(">>> 新字符串的堆内存分配失败: %s\n", strerror(errno));
        return build_empty_string(); // 构建空字符串的结构体
    }

    for(int i = 0; i < thisptr->length; i++){
        newstr[i] = tolower(thisptr->value[i]); // 复制子串的字符到堆内存
    }
    newstr[thisptr->length] = '\0'; // 字符串末尾加上'\0'

    String* newstrptr = build_string(newstr); // 构建子串的结构体
    free(newstr); // 释放newstr的堆内存
    newstr = NULL; // 置空newstr的堆内存指针
    return newstrptr;
} 

String* to_upper(String* thisptr)函数,将字符串转换成大写,会新创建一个字符串结构体。

/**
 * 将字符串转换为大写
 * 
 * @param thisptr 字符串结构体指针
 * @return 转换后的字符串结构体指针(新创建了一个String结构体)
 */
String* to_upper(String* thisptr){
    if(thisptr == NULL){
        return build_empty_string(); // 构建空字符串的结构体
    }

    char* newstr = (char*)malloc(thisptr->length + 1); // 在堆上申请内存

    if(newstr == NULL){
        printf(">>> 新字符串的堆内存分配失败: %s\n", strerror(errno));
        return build_empty_string(); // 构建空字符串的结构体
    }

    for(int i = 0; i < thisptr->length; i++){
        newstr[i] = toupper(thisptr->value[i]); // 复制子串的字符到堆内存
    }
    newstr[thisptr->length] = '\0'; // 字符串末尾加上'\0'

    String* newstrptr = build_string(newstr); // 构建子串的结构体
    free(newstr); // 释放newstr的堆内存
    newstr = NULL; // 置空newstr的堆内存指针
    return newstrptr;
}

当发生错误时(新字符串的堆内存空间分配失败时),这两个函数都会调用strerror(errno)函数,

strerror函数用于将错误码转换为对应的错误描述字符串。函数在<string.h>头文件中,以下是对它的具体介绍:

函数原型char *strerror(int errnum);

它接受一个整数类型的错误码(通常是系统调用或库函数返回的错误码),然后返回一个指向描述该错误码的字符串的指针。这个函数使得程序可以以一种更直观的方式显示错误信息,方便开发者理解和处理错误情况。

String* concat(String* thisptr, const char* str)函数,该函数用于连接两个字符串,会释放掉thisptr中的value所占用的堆空间,重新申请一个新的堆空间,但String结构体还是原来的。

/**
 * 连接两个字符串
 * 
 * @param thisptr 字符串结构体指针
 * @param str 字符串指针 要连接的字符串
 * @return 连接后的字符串结构体指针
*/
String* concat(String* thisptr, const char* str){
    if(thisptr == NULL){
        return build_empty_string(); // 构建空字符串的结构体
    }
    if(str == NULL || *str == '\0'){
        return thisptr;
    }
    
    const char* tmpstr = str;
    int i = 0;
    // 计算字符串的长度
    while(*tmpstr != '\0'){
        // printf(">>> str(%d): %c\n", i, *str);
        i++;
        tmpstr++;
    }

    int newlen = thisptr->length + i; // 计算新的字符串的长度
    char* newstr = (char*)malloc(newlen + 1); // 在堆上申请内存
    for(int j = 0; j < thisptr->length; j++){
        newstr[j] = thisptr->value[j]; // 复制子串的字符到堆内存
    }
    for(int j = thisptr->length; j < newlen; j++){
        newstr[j] = str[j - thisptr->length]; // 复制子串的字符到堆内存
    }
    newstr[newlen] = '\0'; // 字符串末尾加上'\0'

    free(thisptr->value);
    thisptr->value = newstr; // 释放原字符串的堆内存, 并将新的字符串赋值给原字符串的value
    thisptr->length = newlen; // 更新字符串的长度

    return thisptr;
}

void new_string(String* thisptr, const char* str)函数会更新thisptr中value的内容,会将value先释放掉,然后在堆上重新开辟一块内存空间保存str的内容。String结构体保持不变。

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

    if(thisptr == NULL){
        printf(">>> String结构体指针为空!\n");
        return;
    }
    if(str == NULL){
        printf(">>> str参数的值为NULL!\n");
        return;
    }
        
    // 将原字符串的value和length清空
    free(thisptr->value); // 释放原字符串的堆内存
    thisptr->value = NULL;
    thisptr->length = 0;

    const char* tmppos = str; // 先保存str的地址
    if(*str == '\0'){
        thisptr->value = (char*)malloc(sizeof(char) * 1);
        thisptr->value[0] = '\0';
        thisptr->length = 0;
    }else{
        // 先计算str的长度
        int i = 0;
        while(*str != '\0'){
            i++;
            str++;
        }
        thisptr->length = i; //  保存字符的长度
        thisptr->value = (char*)malloc(i+1); // 为value在堆里申请内存
         
        char* tmpval = thisptr->value;
            // 复制字符串到value
        while(*tmppos != '\0'){
            *tmpval = *tmppos;
            tmppos++;
            tmpval++;
        }
        *tmpval = '\0'; // 字符串末尾加上'\0'
    }   
}

本章先介绍这么多函数,后续章节会逐步将String结构体中的所有函数都介绍一遍。

敬请期待!

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

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

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

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

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

打赏作者

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

抵扣说明:

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

余额充值