C语言_根据strstr函数实现了一个灵活的字符串查找函数

函数需要的背景

在最近的串口读写中, 我们需要对从串口出来的数据进行精准查找, 和正确的数据进行判.

注: 在EC20F4G模块下发送AT指令!
比如给串口发送"AT", 成功会返回"OK", 失败返回"ERROR".
给串口发送"AT+CPIN", 查找返回字符串中是否收到READY……

函数想法

由于发送AT指令, 从串口中读取的都是一个字符串, 从该字符串中进行精准查找关键字来进行判断是否成功, 符合需求, 每次都要使用strstr来进行查找, 发现查找的方法都是大致一样的, 代码完全是搬来搬去, 所以封装成一个字符串查找函数, 方便使用.

函数实现

at_fetch.c

/*********************************************************************************
 *      Copyright:  (C) 2021 guanyunpeng 
 *                  All rights reserved.
 *
 *       Filename:  at_fetch.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(22/05/21)
 *         Author:  guanyunpeng <364521112qq.com>
 *      ChangeLog:  1, Release initial version on "22/05/21 18:23:30"
 *                 
 ********************************************************************************/

#include "at_fetch.h"

int at_fetch(char *atreply, char *start_key, char *end_key, char *rbuf, int size)
{
    if( !atreply || !start_key)
    {
        return -1;
    }
    
    char        *rbuf_stat;     //返回字符串的首地址
    char        *rbuf_end;      //返回字符串的尾地址
    int         rv = -1;

    if( rbuf != NULL )
    {
        memset(rbuf, 0, sizeof(*rbuf));
    }

    rbuf_stat = strstr(atreply, start_key);
    if( rbuf_stat == NULL )
    {
        //printf("strstr start_key :%s failure\n", start_key);
        return -1;
    }
    rbuf_stat += strlen(start_key);

    if( end_key != NULL )
    {
        rbuf_end = strstr(rbuf_stat, end_key);
        if( rbuf_end == NULL )
        {
            //printf("strstr end_key %s failure\n", rbuf_end);
            return -2;
        }
    }
    
    if( rbuf != NULL && ((rbuf_end-rbuf_stat) <= size) )
    {
        strncpy(rbuf, rbuf_stat, rbuf_end-rbuf_stat);
    }

    return 0;
}

at_fetch.h

/********************************************************************************
 *      Copyright:  (C) 2021 guanyunpeng 
 *                  All rights reserved.
 *
 *       Filename:  at_fetch.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(22/05/21)
 *         Author:  guanyunpeng <364521112qq.com>
 *      ChangeLog:  1, Release initial version on "22/05/21 18:23:55"
 *                 
 ********************************************************************************/



#ifndef __AT_FETCH_H__
#define __AT_FETCH_H__

#include <stdio.h>
#include <stddef.h>
#include <string.h>

/***************************************************************************************************************
 * 功能:
 * 如果传入atreply, start_key, end_key, buf   : 再传入字符串中找到start_key与end_key之间的字符串返回出去  
 * 如果传入atreply, start_key, end_key, NULL  : 则负责查找该区间的字符串, 不将找到的字符串返回出去
 * 如果传入atreply, start_key, NULL, NULL     : 则只负责查找start_key这个字符串
 *
 * 参数:
 * atreply      :   要解析的字符串
 * start_key    :   需要返回字符串的前一个或多个索引
 * end_key      :   需要返回字符串的后一个或多个索引
 * buf          :   返回的字符串
 * size         :   防止溢出
 *
 * 返回值:
 * rv = 0 成功;     rv <0 失败;     rv = -1 输入参数不正确;     rv = -2 没找到start_key;    rv = -3 没找到end_key
 *
 *************************************************************************************************************/ 
int at_fetch(char *atreply, char *start_key, char *end_key, char *rbuf, int size);

#endif 

测试用例

测试代码

/*******************************************************
 * 发送AT+CGMM 查询模型识别(型号) 并保存到结构体中
 * 发送AT+CIMI 查询国际移动用户识别码 并保存到结构体中
 * ******************************************************/

typedef struct module_ctx_s
{
    char    *manufacturer[128];         //制造商,   AT+CGMI
    char    *information[128];          //模型识别(型号),   AT+CGMM 
    char    *software_version[128];     //软件版本修订标识,     AT+CGMR
    char    *serial_number[128];        //IMEI号(手机序列号),   AT+CGSN
    char    *user_identifier[128];      //国际移动用户识别码,   AT+CIMI

}module_ctx_t;

int atcmd_check_cgmm(comport_t *comport, module_ctx_t *ctx)
{
    char    buf[512];
    char    rbuf[128];
    char    *ptr = NULL;

    memset(buf, 0, sizeof(buf));
    memset(rbuf, 0, sizeof(rbuf));

    if( send_atcmd(comport, "AT+CGMM\r", buf, sizeof(buf), 300) < 0 ) 
    {   
        printf("send_atcmd AT+CGMM failure!\n");
        return -1; 
    }   

    printf("AT+CGMM:%s\n", buf);

    if( at_fetch(buf, "\r\n", "\r\n", (char *)ctx->information, 128) != 0)
    {   
        printf("at_fetch AT+CGMM failure\n");
        return -2;
    }

    //printf("rbuf:%s\n", rbuf);

    return 0;
}

int atcmd_check_cimi(comport_t *comport, module_ctx_t *ctx)
{
    char    buf[512];

    memset(buf, 0, sizeof(buf));

    if( send_atcmd(comport, "AT+CIMI\r", buf, sizeof(buf), 300) < 0 ) 
    {   
        printf("send_atcmd at+cgmr failure!\n");
        return -1; 
    }   
    printf("AT+CIMI:%s\n", buf);

    if( at_fetch(buf, "\r\n", "\r\n", (char *)ctx->user_identifier, 128) != 0)
    {   
        printf("at_fetch at+cimi failure\n");
        return -2; 
    }   

    return 0;
}
int main (int argc, char **argv)
{
    int         rv = -1;
    int         n = -1;
    int         stat = -1;
    comport_t   comport;
    char        rbuf[512];

    module_ctx_t    ctx;

    memset(rbuf, 0, sizeof(rbuf));
    memset(&ctx, 0, sizeof(ctx));

    comport_open(&comport, "/dev/ttyUSB3", 115200, "8n1n");

    atcmd_check_cgmm(&comport, &ctx);
    printf("ctx.information:%s\n", ctx.information);
    
    atcmd_check_cimi(&comport, &ctx);
    printf("ctx.user_identifier:%s\n", ctx.user_identifier);
    
    comport_close(&comport);
    return 0;
}

测试结果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值