1. 程式人生 > >snprintf連續列印封裝:可變引數的巨集定義

snprintf連續列印封裝:可變引數的巨集定義

問題來源:

假設有個結構有很多成員,需要根據成員的不同型別,將所有成員封裝在一個CHAR型別的buf中輸出。

例:

有結構體:

typedef struct CON_PRINTF
{
    CHAR szElem1[BUF_LEN_20];
    CHAR szElem2[BUF_LEN_100];
    INT iIntElem;
          
}CON_PRINTF_ST;
需要根據每個成員的型別不同,列印其成員值。

對snpintf的封裝:

/* 用於連續列印封裝 */
#define continuce_sprintf(uiCurPos, pcBuf, uiBufLen, args...)\
{\
    if ( (uiCurPos) < (uiBufLen))\
    {\
        ((uiCurPos) += (UINT)snprintf((pcBuf + uiCurPos), ((uiBufLen) - (uiCurPos)),\
                                            ##args));\
    }\
}

/* PRI_BEGIN必須寫在最前面 */
#define PRI_BEGIN(uiCurPos,pcBuf,uiBufLen)\
{\
    UINT __uiCurPos = (uiCurPos);\
    UINT __uiBufLen = (uiBufLen);\
    CHAR *__pcBuf = (pcBuf);

/* 中間寫PRI_STR、PRI_INT 等*/
/* PRI_END必須寫在最後面 */
#define PRI_END(uiCurPos) \
    uiCurPos =__uiCurPos; \
}

#define PRI_STR(key,val) continuce_sprintf(__uiCurPos, __pcBuf, __uiBufLen, \
    "\"%s\":\"%s\",",key,val)
#define PRI_INT(key,val) continuce_sprintf(__uiCurPos, __pcBuf, __uiBufLen, \
    "\"%s\":\"%d\",",key,val)
測試函式:
VOID test_for_conPri()
{
    CHAR szBuf[BUF_LEN_100] = {0};
    CHAR szTest1[BUF_LEN_20] = "Test buf 1.";
    CHAR szTest2[BUF_LEN_20] ="Test buf 2.";
    UINT uiCurPos = 0;
    INT iTest1=20;
    CON_PRINTF_ST *pstCON_PriTest = NULL;
    pstCON_PriTest = (CON_PRINTF_ST *)malloc(sizeof(CON_PRINTF_ST));
    if ( NULL == pstCON_PriTest)
    {
        printf("Malloc failed,size :%d.\n",sizeof(CON_PRINTF_ST));
        return ;
    }
    memset(pstCON_PriTest,0,sizeof(CON_PRINTF_ST));
    pstCON_PriTest->iIntElem = iTest1;
    str_cpy(pstCON_PriTest->szElem1,szTest1);
    str_cpy(pstCON_PriTest->szElem2,szTest2);
    /* continuce_sprintf(uiCurPos, szBuf, BUF_LEN_100, szTest1); */
    /* continuce_sprintf(uiCurPos, szBuf, BUF_LEN_100, "%d,",iTest1); */
    /* continuce_sprintf(uiCurPos, szBuf, BUF_LEN_100, "%s,",szTest1); */

    PRI_BEGIN(uiCurPos, szBuf, BUF_LEN_100);
    PRI_STR("buf1 :", pstCON_PriTest->szElem1);
    PRI_STR("buf2 :", pstCON_PriTest->szElem2);
    PRI_INT("int  :", pstCON_PriTest->iIntElem);
    PRI_END(uiCurPos);
    printf("uiCurPos = %u.\n",uiCurPos);
    printf("%s\n",szBuf);

    return;
}
測試結果: