📄 switch.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 + -