【C 语言】字符串模型 ( strstr-while 模型 | 抽象函数模型 | 业务子函数接口定义要点 | 形参指针间接赋值 | 返回值状态 | 形参指针处理 | 形参指针判空 | 形参返回值 )

2023-03-29 21:25:11 浏览数 (1)

文章目录

  • 前言
  • 一、业务子函数接口定义要点
  • 二、完整代码示例

前言

字符串开发模型 :

  • strstr-while/do…while 模型 : 在 字符串 中 查找 子串特征 ;
  • 两头堵模型 : 两个指针变量 , 一个指向首部 , 一个指向尾部 , 进行 翻转 , 逆序 等操作 ;
  • 字符串翻转模型 : 借助 指针 进行翻转 , 或 借助 栈 后进先出的特性 , 进行 翻转 ;

一、业务子函数接口定义要点


在上一篇博客 【C 语言】字符串模型 ( strstr-while 模型 ) 的基础上 , 将相关功能封装成 API 函数 , 将 主函数 与 子业务 函数分离开 ;

  • 自定义函数接口 ;
  • 分离 自定义的 业务子函数 与 主函数 main() ;

定义的接口如下 :

  • 要点
1

形参指针间接赋值 : 主要是获取子串大小 , 通过 int *sub_count 参数的 间接赋值 , 实现函数结果返回 ;

  • 要点
2

返回值状态 : 返回值主要是 反应函数执行状态 , 返回

0

代表函数执行成功 ;

代码语言:javascript复制
/*
 * 获取字符串中子串个数接口
 * char *main_str : 大字符串
 * char *sub_str : 子字符串
 * int *sub_count : 存放查找到的子字符串个数
 * 返回值返回执行状态 , 成功返回 0 , 失败返回失败代码
 */
int get_sub_count(char *main_str, char *sub_str, int *sub_count)
{

    return 0;
}

函数中的要点 :

  • 形参指针处理 : 定义 局部 临时 指针变量 , 接收 函数形参变量 , 尽量不修改 函数 形参 的值 ;
  • 形参指针判空 : 凡是传入的指针 , 一律判定指针是否合法 ;
  • 形参返回值处理 : 返回值不要直接修改 , 先定义临时局部变量保存返回值 , 最后执行完毕 , 再将返回值 通过 间接赋值 赋值给 形参中的 返回值指针 指向的 内存地址 ;
代码语言:javascript复制
/*
 * 获取字符串中子串个数接口
 * char *main_str : 大字符串
 * char *sub_str : 子字符串
 * int *sub_count : 存放查找到的子字符串个数
 * 返回值返回执行状态 , 成功返回 0 , 失败返回失败代码
 */
int get_sub_count(char *main_str, char *sub_str, int *sub_count)
{

    // 为了不修改 函数 形参 的值 , 使用指针变量接收 函数形参
    char *main_str_tmp = main_str;
    char *sub_str_tmp = sub_str;

    // 返回值临时值,  先不要修改 sub_count 指针指向的值 , 最后计算完毕后再修改
    int sub_count_tmp = 0;

    // 判定指针是否合法
    // 如果形参指针为 NULL , 直接退出函数 , 并返回 -1 错误码
    if(main_str_tmp == NULL || sub_str_tmp == NULL || sub_count == NULL)
    {
        printf("error : main_str_tmp == NULL || sub_str_tmp == NULL || sub_count == NULL");
        return -1;
    }


    // 在循环条件中
    //   查找 p 指针指向的字符串中, 是否包含 "abc" 子串
    //   如果包含 , 返回子串第一次出现的指针地址 , 非 0 则执行循环体内容
    //   如果不包含 , 返回 NULL , 如果没有找到 , 退出循环 , 继续向后执行
    while (main_str_tmp = strstr(main_str_tmp, sub_str_tmp))
    {
        // 子串出现次数   1
        sub_count_tmp  ;
        // 跳过当前的 "abc" 子串 , 从后面开始遍历
        main_str_tmp = main_str_tmp   strlen(sub_str_tmp);
        // 如果下一个字节是结尾字节 , 直接退出循环
        if(*main_str_tmp == '')
        {
            break;
        }
    }

    // 指针间接赋值 设置 返回值
    *sub_count = sub_count_tmp;

    return 0;
}

二、完整代码示例


完整代码示例 :

代码语言:javascript复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * 获取字符串中子串个数接口
 * char *main_str : 大字符串
 * char *sub_str : 子字符串
 * int *sub_count : 存放查找到的子字符串个数
 * 返回值返回执行状态 , 成功返回 0 , 失败返回失败代码
 */
int get_sub_count(char *main_str, char *sub_str, int *sub_count)
{

    // 为了不修改 函数 形参 的值 , 使用指针变量接收 函数形参
    char *main_str_tmp = main_str;
    char *sub_str_tmp = sub_str;

    // 返回值临时值,  先不要修改 sub_count 指针指向的值 , 最后计算完毕后再修改
    int sub_count_tmp = 0;

    // 判定指针是否合法
    // 如果形参指针为 NULL , 直接退出函数 , 并返回 -1 错误码
    if(main_str_tmp == NULL || sub_str_tmp == NULL || sub_count == NULL)
    {
        printf("error : main_str_tmp == NULL || sub_str_tmp == NULL || sub_count == NULL");
        return -1;
    }


    // 在循环条件中
    //   查找 p 指针指向的字符串中, 是否包含 "abc" 子串
    //   如果包含 , 返回子串第一次出现的指针地址 , 非 0 则执行循环体内容
    //   如果不包含 , 返回 NULL , 如果没有找到 , 退出循环 , 继续向后执行
    while (main_str_tmp = strstr(main_str_tmp, sub_str_tmp))
    {
        // 子串出现次数   1
        sub_count_tmp  ;
        // 跳过当前的 "abc" 子串 , 从后面开始遍历
        main_str_tmp = main_str_tmp   strlen(sub_str_tmp);
        // 如果下一个字节是结尾字节 , 直接退出循环
        if(*main_str_tmp == '')
        {
            break;
        }
    }

    // 指针间接赋值 设置 返回值
    *sub_count = sub_count_tmp;

    return 0;
}

int main()
{
    // 存在如下字符串, 求下面字符串 "abc" 出现次数
    char *str = "sdfsdfsdabc4548411abc";
    // 记录下 "abc" 子串出现次数
    int count = 0;
    // 要查询的子串
    char sub[] = "abc";

    // 注意返回值 使用 指向 count 变量的指针 间接赋值 进行返回
    int ret = get_sub_count(str, sub, &count);

    // 如果返回非 0 值 , 说明执行失败
    if(ret != 0)
    {
        printf("get_sub_count failed!");
    }

    // 打印子串出现次数
    printf("count = %dn", count);




    // 命令行不要退出
    system("pause");
    return 0;
}

执行结果 :

0 人点赞