尖括號轉義-C語言實現版本

需求:

字符串是xml格式的字符串,但是某個標籤值存在尖括號,需要把'<'替換成"&lt",把'>'替換成"&gt"

例如:

0123456789<Root><>r423><432423<<</Root>3gfdgfd

轉換後

0123456789<Root>&lt&gtr423&gt&lt432423&lt&lt</Root>3gfdgfd

實現:

/*
 * @Author: [email protected] 
 * @Date: 2019-11-26 14:16:58
 * @LastEditTime: 2019-11-26 17:15:19
 * @LastEditors: Please set LastEditors
 * @Description: 指定標籤尖括號轉義
 */

#include <stdio.h>
#include <string.h>
#define USTRD_MAX_LEN 280
#define USTRD_TAG_HEAD "<Root>"
#define USTRD_TAG_TAIL "</Root>"
#define LEFT_ANGLE_BRACKET '<'
#define RIGHT_ANGLE_BRACKET '>'
#define LEFT_ANGLE_BRACKET_ESCAPING "&lt"
#define RIGHT_ANGLE_BRACKET_ESCAPING "&gt"


/**
 * @description: 查找指定地址串中中是否存在尖括號
 * @param pstr_start-起始地址
 *        pstr_end-結束地址
 * @return: 
 */
int find_angle_bracket(char *pstr_start, char *pstr_end)
{
    char *pstr = pstr_start;
    while (pstr <= pstr_end)
    {
        if (*pstr == LEFT_ANGLE_BRACKET || *pstr == RIGHT_ANGLE_BRACKET)
        {
            return 0;
        }
        else
        {
            pstr++;
        }
    }
    return -1;
}




/**
 * @description: 轉義指針所覆蓋到範圍類的尖括號,如果轉義後過長則截斷。
 * @param: pstr_start-起始地址 
 *         pstr_end-結束地址
 *         dest-轉義後字符存放地址
 *         dest_len-dest長度
 * @return: 
 */
int to_escaping(char *pstr_start, char *pstr_end, char *dest, int dest_len)
{
    int idx = 0;
    char *pstr = pstr_start;
    memset(dest, 0, dest_len);
    while (pstr < pstr_end && idx < dest_len)
    {
        if (*pstr != LEFT_ANGLE_BRACKET)
        {
            if (*pstr != RIGHT_ANGLE_BRACKET)
            {
                *(dest + idx) = *pstr;
                idx = idx + 1;
            }
            else
            {
                memcpy(dest + idx, RIGHT_ANGLE_BRACKET_ESCAPING, strlen(RIGHT_ANGLE_BRACKET_ESCAPING));
                idx = idx + strlen(RIGHT_ANGLE_BRACKET_ESCAPING);
            }
        }
        else
        {
            memcpy(dest + idx, LEFT_ANGLE_BRACKET_ESCAPING, strlen(LEFT_ANGLE_BRACKET_ESCAPING));
            idx = idx + strlen(LEFT_ANGLE_BRACKET_ESCAPING);
        }
        pstr++;
    }
}


/**
 * @description:  替換字符串中尖括號,進行轉義
 * @param buf-輸入原串,處理後修改該buf
 *        len-buf長度
 * @return: 0-succ
 */
int replace_ustrd(char *buf, int len)
{
    char dest[USTRD_MAX_LEN * 3];
    char tail[USTRD_MAX_LEN * 3];
    char *pstr_start = NULL;
    char *ustrd_start = strstr(buf, USTRD_TAG_HEAD);
    char *pstr_end = strstr(buf, USTRD_TAG_TAIL);

    pstr_start = ustrd_start + strlen(USTRD_TAG_HEAD);

    if (pstr_start == NULL || pstr_end == NULL)
    {
        //不處理
        return 0;
    }
    if (find_angle_bracket(pstr_start, pstr_end) == -1)
    {
        return 0;
    }
    memset(dest, 0, sizeof(dest));
    to_escaping(pstr_start, pstr_end, dest, sizeof(dest));
    memset(tail, 0x00, sizeof(tail));
    memcpy(tail, pstr_end, strlen(pstr_end));
    snprintf(pstr_start, len - (pstr_start - buf), "%s%s", dest, tail);
    return 0;
}
/**
 * @description: 測試
 * @param 
 * @return:0-succ 
 */
int main()
{
    char *buf = "0123456789<Root><>r423><432423<<</Root>3gfdgfd";
    char arr[10240];
    memset(arr, 0, sizeof(arr));

    memcpy(arr, buf, strlen(buf));
    printf("source = [%s]\n", arr);
    replace_ustrd(arr, sizeof(arr));
    printf("result = [%s]\n", arr);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章