数据传输 -- 字符串报文

1. 字符串报文分类: 固定长度字符串报文,  固定分隔符字符串报文。

 

2. 字符串报文组包

 

3. 字符串报文解析

字符串报文结构体:

typedef struct STRRESVARstu
{
    int nAmount;  //数据域总数
    int nFlag;    //报文类型 0定长域  1分割域
    int *filedlen;	//每个数据域的长度
    int nCompartlen;	//分割符号的长度	
    char szCompart[10];	//分隔符符串
    char **filedaddr;	//指向每个数据域首地址的指针
} STRRESVAR;


 

4. 示例一

#include <iostream>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
using namespace std;

#define STRSTR 0
#define STRINT 1
#define STRDOUBLE 2

typedef struct STRRESVARstu  //字符串报文结构体
{
    int nAmount;
    int nFlag;
    int *filedlen;
    int nCompartlen;
    char szCompart[10];
    char **filedaddr;
} STRRESVAR;
typedef STRRESVAR * PSTRRESVAR;

int strrespre(char *buf, PSTRRESVAR pStrstu)  //解析报文,报文先存储在buf中, pStrstu 为报文结构指针
{
    int i = 0, j = 0;
    char *p1, *p2;
    assert(buf != NULL && pStrstu != NULL && pStrstu->filedlen != NULL);
    assert(pStrstu->filedaddr != NULL);
    if (pStrstu->nFlag == 0)
    {
        for (i=0; i<pStrstu->nAmount; i++)
        {
            pStrstu->filedaddr[i] = buf + j;
            j = j + pStrstu->filedlen[i] + pStrstu->nCompartlen;
        }
    }
    else
    {
        p1 = buf;
        p2 = p1;
        while (p1 != NULL && i<= pStrstu->nAmount)
        {
            pStrstu->filedaddr[i] = p1;
            p2 = strstr(p1, pStrstu->szCompart);
            if (p2 == NULL)
            {
                pStrstu->filedlen[i] = strlen(p1);
                p1 = NULL;
            }
            else
            {
                pStrstu->filedlen[i] = p2 - p1;
                p1 = p2 + pStrstu->nCompartlen;
            }
            i++;
        }
    }
    return 0;
}

char * TrimString(char* szDest)  //去字符串 首尾 空白
{
    int n, nLen;
    if (szDest != NULL)
    {

        for (n = strlen(szDest); n > 0; n--)
        {
            if (!isblank(szDest[n - 1]))  break;
        }
        szDest[n] = '\0';

        nLen = strlen(szDest);
        for (n = 0; n < nLen; n++)
        {
            if (!isblank(szDest[n])) break;
        }
        strcpy(szDest, szDest + n);
    }
    return szDest;
}

int strresvalue(char *buf, STRRESVAR Strstu, int nIndex, void *pValue, int nType) //报文数据域 读取
{
    char szStrbuf[1024];
    assert(buf != NULL && pValue != NULL);
    assert(Strstu.filedlen != NULL && Strstu.filedaddr != NULL);
    assert(nIndex >=0 && nIndex < Strstu.nAmount);
    memset(szStrbuf, 0, sizeof(szStrbuf));

    strncpy(szStrbuf, Strstu.filedaddr[nIndex],Strstu.filedlen[nIndex]);
    TrimString(szStrbuf);

    switch (nType)
    {
        case STRINT :
            *(int *)pValue = atoi(szStrbuf);
            break ;
        case STRDOUBLE:
            *(double *)pValue = atoi(szStrbuf);
            break;
        default:
            strcpy((char *)pValue, szStrbuf);
            break;
    }
    return 0;
}

/*
int main()
{
    cout << "Test Message!" << endl;

    char szCestr[] = "0019999999999999999999kevinX  1234567.89";  //定长报文
    int nCelen[4] = {3, 19, 6, 12};

    int nIndex;
    char *nCeAddr[4], szAccno[20], szName[20];
    double fAmt;
    STRRESVAR stuStr;
    stuStr.nAmount = 4;
    stuStr.nFlag = 0;
    stuStr.filedlen = nCelen;
    stuStr.nCompartlen = 0;
    stuStr.szCompart[0] = 0;
    stuStr.filedaddr = nCeAddr;

    strrespre(szCestr, &stuStr);
    strresvalue(szCestr, stuStr, 0, &nIndex, STRINT);
    strresvalue(szCestr, stuStr, 1, szAccno, STRSTR);
    strresvalue(szCestr, stuStr, 2, szName, STRSTR);
    strresvalue(szCestr, stuStr, 3, &fAmt, STRDOUBLE);

    cout << "id = " << nIndex << endl;
    cout << "accno = " << szAccno << endl;
    cout << "name = " << szName << endl;
    cout << "amt = " << showpoint << fAmt << endl;

    return 0;
}
*/

int main()
{
    cout << "Test Message!" << endl;

    char szCestr[] = "2|!88888888|!kevin_xiang|!1234567.89";	//定分割域报文

    int nIndex, nCeLen[4];
    char *nCeAddr[4], szAccno[20], szName[20];
	double fAmt;
	STRRESVAR stuStr;
    stuStr.nAmount = 4;
    stuStr.nFlag = 1;
    stuStr.filedlen = nCeLen;
    stuStr.nCompartlen = 2;
    strcpy(stuStr.szCompart, "|!");
    stuStr.filedaddr = nCeAddr;
    strrespre(szCestr, &stuStr);

    strresvalue(szCestr, stuStr, 0, &nIndex, STRINT);
    strresvalue(szCestr, stuStr, 1, szAccno, STRSTR);
    strresvalue(szCestr, stuStr, 2, szName, STRSTR);
    strresvalue(szCestr, stuStr, 3, &fAmt, STRDOUBLE);

    cout << "id = " << nIndex << endl;
    cout << "accno = " << szAccno << endl;
    cout << "name = " << szName << endl;
    cout << "amt = " << showpoint << fAmt << endl;

    return 0;
}


 

 

5. 示例二: linux下C读取 ini配置文档

 

需要上面例一 申明的结构体与函数

config.ini文件内容

[SERVER]
NUM=2

[SERVER1]
IP=192.168.0.1
PORT=8888

[SERVER2]
IP=192.168.0.2
PORT=5555

int GetConfigStrValue(char *buf, void *pValue, int nType) //配置项字符串读写
{
    char *nCeAddr[2];
    int nCeLen[2];
    STRRESVAR stuStr;
    stuStr.nAmount = 2;
    stuStr.nFlag = 1;
    stuStr.filedlen = nCeLen;
    stuStr.nCompartlen = 1;
    strcpy(stuStr.szCompart, "=");
    stuStr.filedaddr = nCeAddr;
    strrespre(buf, &stuStr);
    assert(strresvalue(buf, stuStr, 1, pValue, nType) == 0);
    return 0;
}

int GetConfigValue(char *szPath, char *szRoot, char *szName, void *pValue, int nType)	//配置文件读取
{
    FILE *fp;
    int nFlag = 0;
    char buf[1024], szRootExt[100], szNameExt[100];
    assert( (fp = fopen(szPath, "r")) != NULL);
    sprintf(szRootExt, "[%s]", szRoot);
    sprintf(szNameExt, "%s=", szName);
    while (feof(fp) == 0)
    {
        memset(buf, 0, sizeof(buf));
        fgets(buf, sizeof(buf), fp);
        if (buf[0] == '#') continue;

        if (nFlag == 0 && buf[0] != '[') continue;

        else if (nFlag == 0 && buf[0] == '[')
        {
            if (strncmp(buf, szRootExt, strlen(szRootExt)) == 0) nFlag = 1;
        }
        else if (nFlag == 1 && buf[0] == '[')
        {
            break;
        }
        else
        {
            if (strncmp(buf, szNameExt, strlen(szNameExt)) == 0)
            {
                assert(GetConfigStrValue(buf, pValue, nType) == 0);
                fclose(fp);
                return 0;
            }
        }
    }
    fclose(fp);
    return -1;
}

int main()
{
    int nNumber, i, nPort;
    char szRoot[100], szIP[100];

    assert( GetConfigValue("./config.ini", "SERVER", "NUM", &nNumber, STRINT)==0 );
    cout << "No. = " << nNumber << endl;

    for( i=0; i<nNumber; i++ )
    {
        sprintf(szRoot, "SERVER%d", i+1);
        memset(szIP, 0, sizeof(szIP));
        GetConfigValue("./config.ini", szRoot, "IP", szIP, STRSTR);
        GetConfigValue("./config.ini", szRoot, "PORT", &nPort, STRINT);
        cout << "SERVER" << i+1 << " IP-->" << szIP << " PORT-->" << nPort << endl;
    }

    return 0;
}


 

posted @ 2013-08-07 09:37  今晚打酱油_  阅读(690)  评论(0编辑  收藏  举报