工作中的一点遐想

今天工作要整到银联文件,因为初次接触银联收单,对文件格式不清楚,其实就是将银联所给的文件导入到数据库中而已。看以前同事写的代码惨不忍睹。不知道哪位仁兄写的代码如下:memcpy(sDbRecord+47,sFileRecord+106,6);        memcpy(sDbRecord+174+8,sFileRecord+113,4);        memcpy(sDbRecord+179+8,sFileRecord+118,8);       sDBRecod和SFIleRecord都是char*型,他的意思是从文件读一行到sFileRecord中然后copy其中的某个字段到sDbRecord中,比如文件中的第106个起6个字节是流水号,对应数据库结构中的偏移47个字节。再通过类型强转换成对应的数据结构。memcpy ((char *)&htCupTxn, sDbRecord, sizeof (htCupTxn));htCupTxn是一个数据结构与表结构对应。看得我郁闷不已。你连字节段都数得这么清楚了,结构体都已经建好了,干嘛不copy到结构体中。发完牢骚,要新增加一个银联文件,我肯定是不能这么干的了,真不想被后人骂。后来看银联标准,文件格式无非两种,定长后补空格型和带登即相许和符型的。这是我对带分隔符的文件处理的示例代码。在这里我用了宏,在现在开发中我还是比较喜欢用宏的,一方面如果真的要改什么的话,可以改一个宏就可以,方便了以后需求的改动。而且我认为一个函数超过一个屏幕的高度,就应该精简了。除非不能精简.

typedef struct 
{
	char	member1[8+1];
	char	member2[48+1];
}stStructTest;

;
#define STRUCT_MEMBER_LENGTH(x,y,t) sizeof((x).y)/sizeof(t) -1 
#define STRUCT_MEMBER_CUTZERO(x,y) *(((x).y) + STRUCT_MEMBER_LENGTH(x,y,char))=0
#define STRUCT_MEMBER_FILL(x,y,p) memcpy((x).y,p,STRUCT_MEMBER_LENGTH(x,y)) \
								STUCT_MEMBER_CUTZERO(x,y)
#define STRUCT_MEMBER_MIN_STRING(x,y,p) min(strlen(p),STRUCT_MEMBER_LENGTH(x,y,p))
#define STRUCT_MEMBER_STRCPY(x,y,p) memcpy((x)->y,p,STRUCT_MEMBER_MIN_STRING(x,y,p)
static const char* g_delit= " ,|:\n";
//过虑一行最前面的字符  
char * filter_froward(char *line,char c){
	char *p = line ;
	while (*p == c && *p != NULL)
	{
		p++;
	}
	return p ;
}
inline	void getMemString(stStructTest*pData,int i,const char*p){
	switch(i){
		case 0:
			STRUCT_MEMBER_STRCPY(pData,member1,p);
			break ;
		case 1:
			STRUCT_MEMBER_STRCPY(pData,member2,p);
			break ;
      default:
        break ;
	}
}
	//将一行内容对应到数据结构休整中
int format(char* line,stStructTest *ptTest){
	char *p =line;
	stStructTest test;
	int i = 0 ;
	if(*p == NULL || p == NULL)return -1;
	p = filter_froward(line,' ') ;
	if(p == NULL ){
		return -3;
	}
	p = strtok(p,g_delit);
	if(p == NULL)
		return -4;
	do{
		getMemString(&test,i,p);
		i ++ ;
	}while(p = strtok(NULL,g_delit));
	if( i == 2){
		memcpy(ptTest,&test,sizeof(test));
    return 0
  }
	return -1;
}
int file_format(const char*pFileIn,const char*pFileOut){
	FILE *in ;
	unigned int i;
	char line[1024] ;
	stStructTest test ;
	in = fopen(pFileIn,"r") ;
	if( in == NULL){
		return -1 ;
	}
	memset(line, 0, sizeof(line)) ;
	i = 0 ;
	while(fgets(line,sizeof(line),in) != NULL){
		i ++ ;
		if(0 == format(line,&test) ){
			insertToDbs(&test);
		}
		memset(line, 0, sizeof(line)) ;
	}
	fclose(in);
	return i ;
}
	

到于定长格式的就更好搞定。通过宏就行了。本来想有没有办法不要每次格式变了就得修改代码的,后来想了想还是不行,没办法为了好看,结构体还是得定义的。
就通过switch case 吧。
第一次发博客,代码没有测试,估计差不多吧。但是这个代码风格,我觉得那位老兄应该下地域。有时间数字节数何不自定义数据结构呢。更何况插入到数据的那个表现成
的就可以用。哎!!!

posted @ 2010-11-12 23:31  祥子_随波逐流  阅读(218)  评论(1)    收藏  举报