⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 switch.c

📁 s1240 74字节话单二进制格式转换程序,程序结构可用语其他交换机话单格式转换
💻 C
字号:
#include <stdio.h>
#include <string.h>

#define SUCCESS	1
#define ERROR	-1

/* 声明公共变量 */
struct Stru_Source_Record
{
	unsigned char Info1[5];		/* 其他信息								*/
	unsigned char Number[15];	/* 主叫、被叫号码,被叫开始位置不固定 	*/
	unsigned char Year;			/* 年									*/
	unsigned char Month;		/* 月									*/
	unsigned char Day;			/* 日									*/
	unsigned char Hour;			/* 时									*/
	unsigned char Minute;		/* 分									*/
	unsigned char Second;		/* 秒									*/
	unsigned char TimeLen[4];	/* 时长									*/
	unsigned char Info2[8];		/* 其他信息								*/
};

struct Stru_Target_Record
{
	char Calling_Nbr[15];
	char Sep1;
	char Called_Nbr[20];
	char Sep2;
	char Year[4];
	char Sep3;
	char Month[2];
	char Sep4;
	char Day[2];
	char Sep5;
	char Hour[2];
	char Sep6;
	char Minute[2];
	char Sep7;
	char Second[2];
	char Sep8;
	char TimeLen[6];
	char Sep9[2];
};
	
FILE *fp_SourceFile,*fp_CallFile,*fp_TollFile;

/* 函数声明 */
int	 OpenFile(void);	/* 打开所有文件	*/
void CloseFile(void);	/*关闭所有文件	*/
void ShiftData(void);	/*二进制转文本	*/
void InitTargetRecord(struct Stru_Target_Record *Target_Record);					/* 初始化目标结构	*/
void AnalyzeData(struct Stru_Source_Record *SourceRecord,
		struct Stru_Target_Record *TargetRecord);									/* 解析数据,并写入目标结构 */
int  AnalyzeNumber(unsigned char *InStr,int SourcePos,
		int SourceLen,char *OutStr,int TargetPos);									/* 解析主叫、被叫号码 */
void AnalyzeDateTime(unsigned char InChar,char *OutStr,int Pos);					/* 解析日期、时间 */

void main(void)
{
	if  (OpenFile() == SUCCESS)
	{
		ShiftData();
		CloseFile();
	}
	return;
}

int OpenFile(void)
{
	/* 本函数打开所需处理的所有文件 */
	int  li_RetVal = SUCCESS;
	char lc_FileName[50] = "dch.dat";
	char lc_CallName[50] = "dch_call.txt";
	char lc_TollName[50] = "dch_toll.txt";
	
	/* Open source file */
	fp_SourceFile = fopen(lc_FileName,"rb");
	if  (!fp_SourceFile)
	{
		printf("%s cannot open!\n");
		li_RetVal = ERROR;
	}
	else
	{
		/* Open target file*/
		fp_CallFile = fopen(lc_CallName,"w");
		fp_TollFile = fopen(lc_TollName,"w");
		if  (!fp_CallFile || !fp_TollFile)
		{
			printf("Target file can not open!\n");
			CloseFile();
			li_RetVal = ERROR;
		}
	}
	
	return (li_RetVal);
}	

void CloseFile(void)
{
	fclose(fp_SourceFile);
	fclose(fp_CallFile);
	fclose(fp_TollFile);
	return;
}

void ShiftData(void)
{
	/* 本函数进行文件的二进制转换 */
	/* 二进制格式说明:一个块为2048个字节,块头为10个字节,块尾为24个字节,
	   每个块内共有53条记录,每条记录38个字节,有效记录开始标志为0XBB */
	int		li_TotalRecordCount = 0;	/* 文件总记录数 */
	int		li_BlockRecordCount = 0;	/* 块内记录数	*/
	int		li_TotalBlockCount = 0;		/* 总块数		*/
	int		li_ValidRecordCount = 0;	/* 有效记录数	*/
	
	struct  Stru_Source_Record ls_SourceRecord;
	struct  Stru_Target_Record ls_TargetRecord;
	
	/* 跳过10个字节的块头 */
	fseek(fp_SourceFile,10,SEEK_CUR);

	while(!feof(fp_SourceFile))
	{

		/* 显示处理信息 */
		if  (li_TotalRecordCount % 500 == 0 && li_TotalRecordCount > 0)
		{
			printf("处理记录数:%8d    有效记录数:%8d    数据块数:%8d\n",
				li_TotalRecordCount,li_ValidRecordCount,li_TotalBlockCount);
		}

		/* 如果到块尾,则跳过24个字节块尾和10字节块头 */
		if  (li_BlockRecordCount == 53)
		{
			li_BlockRecordCount = 0;			/* 块内记录统计变量清0 	*/
			li_TotalBlockCount++;				/* 统计块数 			*/
			fseek(fp_SourceFile,24+10,SEEK_CUR);
			if  (feof(fp_SourceFile))				/* 文件结束			*/
			{
				break;
			}
		}

		/* 从源文件中读入一条记录 */
		fread(&ls_SourceRecord,sizeof(struct Stru_Source_Record),1,fp_SourceFile);
		
		/* 如果记录标志不为0XBB,则无效 */
		if  (ls_SourceRecord.Info1[0] != 0xBB)
		{
			li_TotalRecordCount++;
			li_BlockRecordCount++;
			continue;
		}
		
		/* 目标记录初始化 */
		InitTargetRecord(&ls_TargetRecord);

		/* 解析数据,并写入目标结构 */
		AnalyzeData(&ls_SourceRecord,&ls_TargetRecord);
		
		/* 写入目标文件 */
		if  (ls_TargetRecord.Called_Nbr[0] == '0'
			|| strncmp(ls_TargetRecord.Called_Nbr,"17909",5) == 0)
		{
			fprintf(fp_TollFile,"%s",ls_TargetRecord.Calling_Nbr);
		}
		else
		{
			fprintf(fp_CallFile,"%s",ls_TargetRecord.Calling_Nbr);
		}
		
		/* 计数变量累加 */
		li_TotalRecordCount++;
		li_BlockRecordCount++;
		li_ValidRecordCount++;
	}

	printf("处理记录数:%8d    有效记录数:%8d    数据块数:%8d\n",
		li_TotalRecordCount,li_ValidRecordCount,li_TotalBlockCount);

	return;
}

void InitTargetRecord(struct Stru_Target_Record *Target_Record)
{
	/* 本函数对目标串进行初始化 */
	memset(Target_Record->Calling_Nbr,' ',sizeof(struct Stru_Target_Record));
	
	/* 字段间以分号分隔 */
	Target_Record->Sep1 = ',';
	Target_Record->Sep2 = ',';
	Target_Record->Sep5 = ',';
	Target_Record->Sep8 = ',';
	
	/* 年月日之间以'-'分隔 */
	memcpy(Target_Record->Year,"20",2);
	Target_Record->Sep3 = '-';
	Target_Record->Sep4 = '-';
	
	/* 时分秒之间以':'分隔 */
	Target_Record->Sep6 = ':';
	Target_Record->Sep7 = ':';
	
	/* 结尾加回车 */
	Target_Record->Sep9[0] = '\n';
	Target_Record->Sep9[1] = 0x00;
}	

void AnalyzeData(struct Stru_Source_Record *SourceRecord,struct Stru_Target_Record *TargetRecord)
{
	/* 本函数解析源二进制数据,并写入目标结构 */
	int		li_SourcePos=0;
	int		li_TargetPos=0;
	char	lc_Buffer[20];
	long	ll_TimeLen;
	
	int		li_CallingFlag = 1;		/* 主叫号码标志,1表示主叫,0表示被叫			*/
	int		li_NumberOverFlag  = 0;	/* 解析主被叫号码是否结束标志,0没结束,1结束	*/
	int		li_Tmp;
	
	li_TargetPos = 0;
	/* 解析主叫号码 */
	li_SourcePos = AnalyzeNumber(SourceRecord->Number,li_SourcePos,sizeof(SourceRecord->Number),
		TargetRecord->Calling_Nbr,li_TargetPos);
	
	/* 判断主叫、被叫之间的分隔符 */
	for ( ; li_SourcePos < sizeof(SourceRecord->Number); li_SourcePos++)
	{
		sprintf(lc_Buffer,"%2x",SourceRecord->Number[li_SourcePos]);
		if  (lc_Buffer[0] == ' ')
		{	/* 补上丢失的高位0 */
			lc_Buffer[0] = '0';
		}
		
		if  (lc_Buffer[0] >='0' && lc_Buffer[0] <= '9')
		{	/* 如果被叫号码从高4位开始,则退出 */
			break;
		}
		
		if  (lc_Buffer[1] >= '0' && lc_Buffer[1] <= '9')
		{	/* 如果被叫号码从低4位开始,则先写入被叫的首位 */
			TargetRecord->Called_Nbr[0] = lc_Buffer[1];
			li_SourcePos++;		/* 源字串位置指向下一个字节 */
			li_TargetPos = 1;	/* 目标下标位置指向第二个字节,即1 */
			break;
		}
	}
		
	/* 解析被叫号码 */
	AnalyzeNumber(SourceRecord->Number,li_SourcePos,sizeof(SourceRecord->Number),
		TargetRecord->Called_Nbr,li_TargetPos);

	/* 解析日期、时间 */
	AnalyzeDateTime(SourceRecord->Year,  TargetRecord->Year,  2);
	AnalyzeDateTime(SourceRecord->Month, TargetRecord->Month, 0);
	AnalyzeDateTime(SourceRecord->Day,   TargetRecord->Day,   0);
	AnalyzeDateTime(SourceRecord->Hour,  TargetRecord->Hour,  0);
	AnalyzeDateTime(SourceRecord->Minute,TargetRecord->Minute,0);
	AnalyzeDateTime(SourceRecord->Second,TargetRecord->Second,0);
	
	/* 计算时长 */
	ll_TimeLen =  SourceRecord->TimeLen[0] * 16777216
				+ SourceRecord->TimeLen[1] * 65535
				+ SourceRecord->TimeLen[2] * 256
				+ SourceRecord->TimeLen[3];
	memset(lc_Buffer,0x00,sizeof(lc_Buffer));
	sprintf(lc_Buffer,"%d",ll_TimeLen);
	
	/* 将时长按右对齐传入目标结构中 */
	li_SourcePos = strlen(lc_Buffer) - 1;
	li_TargetPos = 5;
	while(li_SourcePos>=0)
	{
		TargetRecord->TimeLen[li_TargetPos] = lc_Buffer[li_SourcePos];
		li_SourcePos--;
		li_TargetPos--;
	}
}	

int  AnalyzeNumber(unsigned char *InStr,int SourcePos,int SourceLen,char *OutStr,int TargetPos)
{
	/* 本函数解析主叫、被叫号码,将结果写入目标串,返回结束的下标位置。
		InStr:		二进制15位主叫、被叫号码
		SourcePos:	InStr的开始位置
		OutStr:	输出结果字串,为主叫或被叫号码
		TargetPos: OutStr的开始位置	*/
	int  li_NumberOverFlag = 0;
	int  li_Tmp;
	char lc_Buffer[100];

	for  ( ; SourcePos < SourceLen; SourcePos++ )
	{	
		/* 取出号码字节的高4位和低4位,放到lc_Buffer的第0、1字节中 */
		sprintf(lc_Buffer,"%2x",InStr[SourcePos]);
		if  (lc_Buffer[0] == ' ')
		{	/* 补上丢失的高位0 */
			lc_Buffer[0] = '0';
		}
		
		for (li_Tmp = 0; li_Tmp < 2;li_Tmp++)
		{	/* 如果是数字则写入到目标串 */
			if  (lc_Buffer[li_Tmp] >= '0' && lc_Buffer[li_Tmp] <= '9')
			{
				OutStr[TargetPos] = lc_Buffer[li_Tmp];
				TargetPos++;
			}
			else
			{	/* 如果不是数字,则号码结束 */
				li_NumberOverFlag = 1;
				break;
			}
		}
		if  (li_NumberOverFlag == 1)
		{
			break;
		}
	}
	
	return (SourcePos);
}
	
void AnalyzeDateTime(unsigned char InChar,char *OutStr,int Pos)		/* 解析日期、时间 */
{
	char lc_Buffer[10];
	
	sprintf(lc_Buffer,"%2x",InChar);
	if  (lc_Buffer[0] == ' ')
	{	/* 补上丢失的高位0 */
		lc_Buffer[0] = '0';
	}
	memcpy(OutStr+Pos,lc_Buffer,2);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -