求高手:结构体解码时条用另一个结构体时出错,vc6.0中编译通过,但结果错误
#include "stdio.h"#include<string.h>
#include <STDLIB.H>
struct{
unsigned int un;
unsigned int gb;
unsigned char zw[2];
unsigned int cw;
} ungb[]={
{0x662F, 0xCAC7 ,"是",0x4239 },
{0x4E00, 0xD2BB ,"一",0x5027 },
{0x6761, 0xCCF5 ,"条",0x4485 },
{0x6D4B, 0xB2E2 ,"测",0x1866 },
{0x8BD5, 0xCAD4 ,"试",0x4252 },
{0x77ED, 0xB6CC ,"短",0x2244 },
{0x4FE1, 0xD0C5 ,"信",0x4837 },
{0x8FD9, 0xD5E2 ,"这",0x5366 },
};
typedef struct {
char SCA[16]; // 短消息服务中心号码
char TPA[16]; // 目标号码或回复号码
char TP_PID; // 用户信息协议标识
char TP_DCS; // 用户信息编码方式
char TP_SCTS[16];// 服务时间戳字符串
char TP_UD[161]; // 原始用户信息(编码前或解码后)
char index; // 消息序号,在读取时用到
} SM_PARAM;
//////////////////////////////////////////////////////////////////
int gsmString2Bytes( unsigned char* pSrc, unsigned char* pDst, int nSrcLength)
{
int i=0;
for(i=0; i<nSrcLength;i+=2);
{ if(*pSrc >='0' && *pSrc<='9')
{
*pDst = (*pSrc - '0') << 4;
}
else
{
*pDst = (*pSrc - 'A' + 10) << 4;
}
pSrc++;
if(*pSrc>='0' && *pSrc<='9')
{
*pDst |= *pSrc - '0';
}
else
{
*pDst |= *pSrc - 'A' + 10;
}
pSrc++;
pDst++;
}
return nSrcLength / 2;
}
//////////////////////////////////////////
gsmDecodeUcs2(const unsigned char *pSrc,unsigned char *pDst,int nSrcLength)
{
unsigned char i,r;
int nDstLength;
unsigned int uncod;
for(i=0;i<nSrcLength;i+=2)
{
uncod=(((unsigned int)*(pSrc))<<8) & ((unsigned int)*(pSrc++));//此处是生成的数据与ungb结构体一致
for(r=0;r<8;r++)
{
if(ungb[r].un == uncod) //查询ungb中是否有此数据
{
*pDst++ = ungb[r].zw[1];
*pDst++ = ungb[r].zw[0];
}
else *pDst++ = 0;
}
}
*pDst='\0';
nDstLength=nSrcLength*2;
return nDstLength;
}
/*-------两两颠倒的字符串转换为正常顺序的字符串----- */
/* 如:"683158812764F8" --> "8613851872468"*/
int gsmSerializeNumbers(const char* pSrc, char* pDst, int nSrcLength)
{
int nDstLength,i; /* 目标字符串长度 */
char ch; /* 用于保存一个字符 */
nDstLength = nSrcLength; /* 复制串长度 */
for(i=0;i<nSrcLength;i+=2) /* 两两颠倒 */
{
ch = *pSrc++; /* 保存先出现的字符 */
*pDst++ = *pSrc++; /* 复制后出现的字符 */
*pDst++ = ch; /* 复制先出现的字符 */
}
if(*(pDst-1) == 'F') /* 最后的字符是'F'吗?*/
{
pDst--;
nDstLength--; /* 目标字符串长度减1 */
}
*pDst = '\0'; /* 输出字符串加个结束符 */
return nDstLength; /* 返回目标字符串长度 */
}
//------------------------------------
int gsmDecodePdu(unsigned char* pSrc, SM_PARAM *pDst)
{
int nDstLength; /* 目标串长度 */
unsigned char tmp; /* 内部用的临时字节变量 */
unsigned char buf[256]; /* 内部用的缓冲区*/
gsmString2Bytes(pSrc, &tmp, 2); /* 取长度 */
tmp = (tmp - 1) * 2; /* SMSC号码串长度 */
pSrc += 4; /* 指针后移 */
gsmSerializeNumbers(pSrc, pDst->SCA, tmp); /* 转换号码到目标串*/
pSrc += tmp; /* 指针后移*/
gsmString2Bytes(pSrc, &tmp, 2); /* 取基本参数 */
pSrc += 2; /* 指针后移 */
if(tmp & 0x80)
{
gsmString2Bytes(pSrc, &tmp, 2); /* 取长度 */
if(tmp & 1) tmp += 1; /* 调整奇偶性*/
pSrc += 4; /* 指针后移 */
gsmSerializeNumbers(pSrc, pDst->TPA, tmp); /* 取号码 */
pSrc += tmp; /* 指针后移 */
}
gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_PID, 2); /* 取协议标识 */
pSrc += 2; /* 指针后移 */
gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_DCS, 2); /* 取编码方式 */
pSrc += 2; /* 指针后移*/
gsmSerializeNumbers(pSrc, pDst->TP_SCTS, 14); /* 服务时间戳字符串*/
pSrc += 14; /* 指针后移 */
gsmString2Bytes(pSrc, &tmp, 2); /* 用户信息长度(TP-UDL) */
pSrc += 2; /* 指针后移 */
nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2); /* 格式转换 */
nDstLength = gsmDecodeUcs2(buf, pDst->TP_UD, nDstLength); /* 转换到TP-DU */
return nDstLength; /* 返回目标字符串长度 */
}
void main(void)
{
unsigned char chr] ="0891683108200805F0040D91683188902848F4000850208151754500108FD9662F4E0067616D4B8BD577ED4FE1";
int tt,nn;
SM_PARAM *pDst1;
pDst1=(SM_PARAM*)malloc(sizeof(SM_PARAM));
tt=gsmDecodePdu(chr,pDst1);
nn=strlen(pDst1->TP_UD);
printf("mesage=%s",pDst1->TP_UD);
free(pDst1);
}
//希望的答案是‘mesage=这是一条测试短信’