#define _CSV_H
#ifdef __cplusplus
extern "C" {
#endif
/*连续预读20行都没有解析正确的CSV字段,则退出程序*/
#define ERROR_LINE 10
#define RIGHT_LINE 3000
extern int iscsvfield(const char *,int);
extern void *csv2obj(const char *,unsigned ,int,int,void *);
extern void *readcsv(void *,unsigned,int,int,void *);
extern char *getstr4stack(void *);
extern void destroyerrorline(void *);
extern void destroycsv(void *);
extern void destroycsvrow(void *);
#ifdef __cplusplus
}
#endif
#endif
#include #include #include #include #include "csv.h" #include "mylib.h" #include "mymethod.h" int iscsvfield(const char *f_csvfield,int f_flag){ int v_flagnums; char v_flagstr[3]={f_flag,f_flag,'\\0'}; if((v_flagnums=chrtotal(f_csvfield,f_flag))>0){ if(v_flagnums%2==0&&v_flagnums==2*strtotal(f_csvfield,v_flagstr)) return 0; else return -1; } return 0; } void *csv2obj(const char *f_csvstr,unsigned f_fields,int f_flag,int f_break,void *f_obj){ char *v_csvstr,*v_break,*v_tmpfield,*v_field; char v_flagstr[3]={f_flag,f_flag,'\\0'}; unsigned v_fields=0; int v_csvstrlen; s_link *v_obj; if(!f_csvstr||(v_csvstrlen=strlen(f_csvstr))==0) return NULL; v_csvstr=newstr(f_csvstr); if(v_csvstr[v_csvstrlen-1]=='\ '){ v_csvstr[v_csvstrlen-1]='\\0'; v_csvstrlen=v_csvstrlen-1; } if(*v_csvstr!=f_flag||v_csvstr[v_csvstrlen-1]!=f_flag){ return NULL; } if(!f_obj){ if((v_obj=init_slink(NULL))==NULL){ fprintf(stderr,"csv2obj malloc() error"); return NULL; } } else v_obj=(s_link*)f_obj; v_tmpfield=v_csvstr; v_break=v_csvstr; while((v_break=strchr(v_break,f_break))!=NULL){ if(*(v_break-1)!=f_flag||*(v_break+1)!=f_flag){ v_break++; continue; } *v_break='\\0'; *(v_break-1)='\\0'; if(iscsvfield(v_tmpfield+1,f_flag)==0){ /*存储CSV字段*/ v_field=newstr(v_tmpfield+1); if(s_addnode(v_obj,v_field)==NULL){ v_fields=-1; break; } v_tmpfield=v_break+1; v_fields++; } *(v_break-1)=f_flag; *v_break=f_break; v_break++; } if(v_fields!=-1){ v_csvstr[v_csvstrlen-1]='\\0'; if(iscsvfield(v_tmpfield+1,f_flag)==0){ /*存储CSV字段*/ v_field=newstr(v_tmpfield+1); if(s_addnode(v_obj,v_field)==NULL){ v_fields=-1; } v_fields++; } else v_fields=0; } if(v_fields&&v_fields==f_fields){ return v_obj; } s_destroylink(&v_obj); if(!f_obj) free(v_obj); free(v_csvstr); return NULL; } void *readcsv(void *f_fptr,unsigned f_fields,int f_flag,int f_break,void *f_obj){ char *v_csvbuf; d_queue *v_csv,*v_tmpcsv; s_stack v_tmpcsvbuf; int v_errorlines,v_rightrows=0; if(!f_fptr||!f_fields) return NULL; if(!f_obj){ if((v_csv=init_dqueue(NULL))==NULL){ fprintf(stderr,"readcsv malloc() error"); return NULL; } } else v_csv=(d_queue*)f_obj; if(init_sta ck(&v_tmpcsvbuf)==NULL){ fprintf(stderr,"readcsv init_stack() error"); if(!f_obj) free(v_csv); } v_tmpcsv=v_csv; v_errorlines=0; while((v_csvbuf=read_line(f_fptr,NULL,NULL))!=NULL){ s_link *v_csvrow; if(v_errorlines>ERROR_LINE-1) break; if((v_csvrow=(s_link*)csv2obj(v_csvbuf,f_fields,f_flag,f_break,NULL))!=NULL){ /*丢弃错误的行*/ destroyerrorline(&v_tmpcsvbuf); if(push_dqueue(v_csv,v_csvrow)==NULL){ free(v_csvrow); v_errorlines=ERROR_LINE; break; } if(v_csv->_total==RIGHT_LINE) break; free(v_csvbuf); } else{ int v_csvbuflen=strlen(v_csvbuf); if(v_csvbuflen) v_errorlines++; v_csvbuf[v_csvbuflen]='\ '; v_csvbuf[v_csvbuflen+1]='\\0'; push_stack(&v_tmpcsvbuf,v_csvbuf); if((v_csvbuf=getstr4stack(&v_tmpcsvbuf))==NULL){ v_errorlines=ERROR_LINE; break; } /*v_csvbuf[strlen(v_csvbuf)-1]='\\0';*/ if((v_csvrow=(s_link*)csv2obj(v_csvbuf,f_fields,f_flag,f_break,NULL))!=NULL){ if(push_dqueue(v_csv,v_csvrow)==NULL){ free(v_csvrow); v_errorlines=ERROR_LINE; break; } if(v_csv->_total==RIGHT_LINE) break; free(v_csvbuf); v_errorlines=0; continue; } else{ push_stack(&v_tmpcsvbuf,v_csvbuf); } } } destroyerrorline(&v_tmpcsvbuf); if(v_errorlines>ERROR_LINE-1){ destroycsv(v_csv); if(!f_obj) free(v_csv); v_csv=NULL; } if(v_csv->_total==0){ if(!f_obj) free(v_csv); v_csv=NULL; } return v_csv; } char *getstr4stack(void *f_stack){ s_stack *v_stack; char *v_errorbuf,*v_tmperrorbuf; v_stack=(s_stack *)f_stack; if(!v_stack||!v_stack->_total) return NULL; v_errorbuf=(char*)pop_stack(v_stack); /*v_errorbuf[strlen(v_errorbuf)-1]='\\0';*/ while((v_tmperrorbuf=(char*)pop_stack(v_stack))!=NULL){ int v_errbuflen=strlen(v_errorbuf); if((v_tmperrorbuf=(char*)realloc(v_tmperrorbuf, (strlen(v_tmperrorbuf)+v_errbuflen+1)*sizeof(char)))==NULL){ return NULL; } strncat(v_tmperrorbuf,v_errorbuf,v_errbuflen+1); free(v_errorbuf); v_errorbuf=v_tmperrorbuf; } return v_errorbuf; } void destroyerrorline(void *f_stack){ s_stack *v_stack; char *v_errorbuf,*v_tmperrorbuf; v_stack=(s_stack *)f_stack; if(!v_stack||!v_stack->_total) return; while((v_errorbuf=(char*)pop_stack(v_stack))!=NULL){ fprintf(stderr,"%s ylib.h" #include "csv.h" #include "mymethod.h" int f_fd; void printfield(s_link *f_row){ if(f_row){ while(f_row->_next_snode!=NULL){ if(strlen((char*)f_row->_data)){ buf_write(f_fd,"\\"