Board logo

标题: 文件数据分析比较(Rev 02!)大佬有更好的思路请多多指教!!! [打印本页]

作者: Gin_Q    时间: 2020-3-17 11:32     标题: 文件数据分析比较(Rev 02!)大佬有更好的思路请多多指教!!!

本帖最后由 Gin_Q 于 2020-4-10 11:17 编辑

感谢red2020--_--||你们提供的帮助!
3W+ 数据1秒不到搞定,真的不要太快!
  1. #if 0
  2.         By Cool_Breeze
  3.         Rev 02
  4.         #endif
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stddef.h>
  10. #include <malloc.h>
  11. #include <float.h>
  12. #include <errno.h>
  13. typedef unsigned long long intll;
  14. FILE* fileptr(char* file, char* mode);
  15. //源文件解析
  16. void scantext(FILE* fp, intll* inu);
  17. void getname(FILE* fp, char* name, intll si);
  18. void getdata(FILE* fp, double* max, double* min, double* avg, double* sum, double* count,\
  19.         intll ns, intll nl, char* max_n, char* min_n);
  20. //limit文件解析
  21. void limittext(FILE* fp, intll* inu);
  22. void getlimitdata(FILE* fp,char* name, char* item, char* comp, double* data);
  23. int compare(char *cmp,double s,double l);
  24. void output(FILE* fp,int flag,int n,char* name,char* litem,double sdata,char* comp,double ldata);
  25. #define LINES 1024
  26. #define NAMESIZE 100
  27. #define COMPSIZE 3
  28. static char temp[LINES];
  29. static char const delim[]=",";
  30. static int ERROR=0;//ERROR退出值,0代表Pass ,非0代表Fail
  31. int main(int argc,char **argv)
  32. {
  33.         static char usage[NAMESIZE]="-s source.csv\n-l limit.csv\n-r result.csv";
  34.         static char source[NAMESIZE];
  35.         static char limit[NAMESIZE];
  36.         static char result[NAMESIZE];
  37.         register int opt=0;
  38.         while ((opt = getopt(argc,argv,"-s:-l:-r:")) != -1)
  39.                 switch (opt)
  40.                 {
  41.                         case 's': strcpy(source,optarg);break;
  42.                         case 'l': strcpy(limit,optarg);break;
  43.                         case 'r': strcpy(result,optarg);break;
  44.                         default : printf("%s\n",usage);exit(EXIT_SUCCESS);
  45.                 }
  46.                
  47.         FILE* fpi=fileptr(source,"rb");
  48.         FILE* lpi=fileptr(limit,"rb");
  49.         FILE* fpo=fileptr(result,"wb");
  50.         
  51.         //开始源文件解析
  52.         static intll inu,isize=NAMESIZE;
  53.         scantext(fpi,&inu);
  54.         char* iname=(char*)calloc(inu,sizeof(char)*isize);
  55.         char* max_n=(char*)calloc(inu,sizeof(char)*isize);
  56.         char* min_n=(char*)calloc(inu,sizeof(char)*isize);
  57.         getname(fpi, iname, isize);
  58.         double* max=(double*)calloc(inu,sizeof(double));
  59.         double* min=(double*)calloc(inu,sizeof(double));
  60.         double* avg=(double*)calloc(inu,sizeof(double));
  61.         double* sum=(double*)calloc(inu,sizeof(double));
  62.         double* count=(double*)calloc(inu,sizeof(double));
  63.         register intll i=0;
  64.         for (i=0;i<inu;i++) *(min+i)=DBL_MAX, *(max+i)=LDBL_MIN;
  65.         getdata(fpi, max, min, avg, sum, count, isize, inu, max_n, min_n);
  66.         //源文件解析完成
  67.         
  68.         //开始limit文件解析
  69.         static intll lnu,lsize=NAMESIZE;
  70.         limittext(lpi,&lnu);
  71.         char* lname=(char*)calloc(lnu,sizeof(char)*lsize);
  72.         char* litem=(char*)calloc(lnu,sizeof(char)*lsize);
  73.         char* comp=(char*)calloc(lnu,sizeof(char)*COMPSIZE);
  74.         double* ldata=(double*)calloc(lnu,sizeof(double)*lsize);
  75.         getlimitdata(lpi, lname, litem, comp, ldata);
  76.         //limit文件解析完成
  77.         
  78.         static const char li_comp[3][10]={{"Max"},{"Min"},{"Avg"}};
  79.         
  80.         register int j=0,flag=1;
  81.         register int k=0;
  82.         fprintf(fpo," Result\r\n");
  83.         fprintf(fpo," Nu, Item, Options, %s, Comp, %s, Result\r\n",source,limit);
  84.         for (i=0;i<lnu;i++)
  85.                 for (j=0;j<inu-1;j++)
  86.                         if ( ! strcmp(lname+i*NAMESIZE,iname+(j+1)*NAMESIZE) )//匹配项目名 (j+1)跳过第一项数据生成时间项
  87.                         {
  88.                                 for (k=0;k<3;k++) if ( ! strcmp(litem+i*NAMESIZE,li_comp[k]) ) break;
  89.                                 switch (k)
  90.                                 {
  91.                                         case 0:        flag=compare(comp+i*COMPSIZE,*(max+j),*(ldata+i));
  92.                                                         output(fpo,flag,(j+1),lname+i*NAMESIZE,litem+i*NAMESIZE,max[j],comp+i*COMPSIZE,ldata[i]);
  93.                                                         break;
  94.                                         case 1:        flag=compare(comp+i*COMPSIZE,*(min+j),*(ldata+i));
  95.                                                         output(fpo,flag,(j+1),lname+i*NAMESIZE,litem+i*NAMESIZE,min[j],comp+i*COMPSIZE,ldata[i]);
  96.                                                         break;
  97.                                         case 2:        flag=compare(comp+i*COMPSIZE,*(avg+j),*(ldata+i));
  98.                                                         output(fpo,flag,(j+1),lname+i*NAMESIZE,litem+i*NAMESIZE,avg[j],comp+i*COMPSIZE,ldata[i]);
  99.                                                         break;
  100.                                         default :        break;
  101.                                 }
  102.                         }
  103.         //输出源文件和limit文件内容
  104.         fprintf(fpo," %s\r\n",limit);
  105.         fprintf(fpo," Nu, Item, Comp_Item, Comp, Data\r\n");
  106.         for (i=0;i<lnu;i++)  fprintf(fpo,"%-d, %s, %s, %s,%lf\r\n",i+1,lname+i*NAMESIZE,litem+i*NAMESIZE,comp+i*COMPSIZE,*(ldata+i));
  107.         fprintf(fpo," %s\r\n",source);
  108.         fprintf(fpo," Nu, Item, Count, Max, Max_Date, Min, Min_Date, Sum, Avg\r\n");
  109.         for (i=0;i<inu-1;i++) fprintf(fpo,"%-d, %s, %.0lf, %.6lf, %s, %.6lf, %s, %.6lf, %.6lf\r\n",\
  110.         i+1,iname+(i+1)*isize,*(count+i),*(max+i),max_n+i*isize,*(min+i),min_n+i*isize,*(sum+i),*(avg+i));
  111.         
  112.         free(iname);
  113.         free(max);
  114.         free(min);
  115.         free(avg);
  116.         free(sum);
  117.         free(count);
  118.         free(max_n);
  119.         free(min_n);
  120.         free(lname);
  121.         free(litem);
  122.         free(comp);
  123.         free(ldata);
  124.         fclose(fpi);
  125.         fclose(fpo);
  126.         return ERROR;
  127. }
  128. FILE* fileptr(char* file, char* mode)
  129. {
  130.         FILE* fp = fopen(file,mode);
  131.         if (fp == NULL)
  132.         {
  133.                 printf("open file fail!:%s",strerror(errno));
  134.                 exit(EXIT_FAILURE);
  135.         }
  136.         return fp;
  137. }
  138. void scantext(FILE* fp, intll* inu)
  139. {
  140.         rewind(fp);
  141.         register intll i=0;//记录项目数
  142.         char *p;
  143.         fgets(temp,LINES,fp);
  144.         p=strtok(temp,delim);
  145.         while(p != NULL)
  146.         {
  147.                 i++;
  148.                 p=strtok(NULL,delim);
  149.         }
  150.         *inu=i;
  151. }
  152. void getname(FILE* fp, char* name, intll si)
  153. {
  154.         rewind(fp);
  155.         fgets(temp,LINES,fp);
  156.         char* p=strtok(temp,delim);
  157.         register intll i=0,l;
  158.         while (p != NULL)
  159.         {
  160.                 strcpy(name+i*si,p);
  161.                 p=strtok(NULL,delim);
  162.                 i++;
  163.         }
  164.         i--;
  165.         l=strlen(name+i*si);
  166.         while (l--)
  167.                 if (*(name+i*si+l) == 0xA || *(name+i*si+l) == 0xD)//最后一列丢弃换行,回车
  168.                         *(name+i*si+l) = '\0';
  169.                 else break;
  170. }
  171. void getdata(FILE* fp, double* max, double* min, double* avg, double* sum, double* count,\
  172.         intll ns, intll nl, char* max_n, char* min_n)
  173. {
  174.         rewind(fp);
  175.         fgets(temp,LINES,fp);
  176.         
  177.         register double t=0;
  178.         register intll i=0;
  179.         register intll cou=0;
  180.         register intll stl=0;
  181.         char *p=NULL;
  182.         char *pb=NULL;
  183.         
  184.         while (fgets(temp,LINES,fp))
  185.         {
  186.                 cou++;
  187.                 i=0;
  188.                 p=pb=strtok(temp,delim);//按指定字符分割字符串 ,pb指向字符串的第一列数据
  189.                 if ( cou == 1 )
  190.                 {
  191.                         int i;
  192.                         stl=strlen(pb);
  193.                         for (i=0;i<nl-1;i++)
  194.                         {
  195.                                 memmove(max_n+i*ns,pb,stl);
  196.                                 *(max_n+i*ns+stl)='\0';
  197.                                 memmove(min_n+i*ns,pb,stl);
  198.                                 *(min_n+i*ns+stl)='\0';
  199.                         }
  200.                 }
  201.                 do
  202.                 {
  203.                         p=strtok(NULL,delim);//遍历每一项数据
  204.                         if (p == NULL) break;
  205.                         t=atof(p);
  206.                         stl=strlen(pb);
  207.                         if (t > *(max+i))
  208.                         {
  209.                                 *(max+i) = t;
  210.                                 memmove(max_n+i*ns,pb,stl);
  211.                                 *(max_n+i*ns+stl)='\0';
  212.                         }
  213.                         if (t < *(min+i))
  214.                         {
  215.                                 *(min+i) = t;
  216.                                 memmove(min_n+i*ns,pb,stl);
  217.                                 *(min_n+i*ns+stl)='\0';
  218.                         }
  219.                         *(sum+i)+=t;
  220.                         i++;
  221.                 }while (1);
  222.         }
  223.         register intll j;
  224.         for (j=0; j<nl-1; j++)//如果最后一行字符串小于标准列数,单独计算平均值和计数器
  225.         {
  226.                 if (j < i) *(avg+j)=*(sum+j)/cou,*(count+j)=cou;
  227.                 else *(avg+j)=*(sum+j)/(cou-1),*(count+j)=cou-1;
  228.         }
  229. }
  230. //limit文件解析
  231. void limittext(FILE* fp, intll* inu)
  232. {
  233.         rewind(fp);
  234.         register intll i=0;
  235.         while (fgets(temp,LINES,fp))
  236.                 i++;//读取行数
  237.         *inu=i;
  238. }
  239. void getlimitdata(FILE* fp,char* name, char* item, char* comp, double* data)
  240. {
  241.         rewind(fp);
  242.         char* p=temp;
  243.         register intll i=0,count=0,psize=0;
  244.         while (fgets(temp,LINES,fp))
  245.         {
  246.                 count=0;
  247.                 p=strtok(temp,delim);
  248.                 do
  249.                 {
  250.                         if(p == NULL) break;
  251.                         psize=strlen(p);//按分割每个符分割字符串
  252.                         switch (count)
  253.                         {
  254.                                 case 0:        memmove(name+i*NAMESIZE,p,psize);
  255.                                                 *(name+i*NAMESIZE+psize)='\0';break;
  256.                                 case 1: memmove(item+i*NAMESIZE,p,psize);
  257.                                                 *(item+i*NAMESIZE+psize)='\0';break;
  258.                                 case 2:        memmove(comp+i*COMPSIZE,p,psize);
  259.                                                 *(comp+i*COMPSIZE+psize)='\0';break;
  260.                                 case 3: *(data+i) = atof(p);break;
  261.                                 default : break;
  262.                         }
  263.                         count++;
  264.                 } while (p=strtok(NULL,delim));
  265.                 i++;
  266.         }
  267. }
  268. //数据比较
  269. int compare(char *cmp,double s,double l)
  270. {
  271.         if (! strcmp(cmp,"<")) return (s < l)? 1:0;
  272.         else if (! strcmp(cmp,">")) return (s > l)? 1:0;
  273.         else if (! strcmp(cmp,"=")) return (s = l)? 1:0;
  274.         else if (! strcmp(cmp,"<=")) return (s <= l)? 1:0;
  275.         else if (! strcmp(cmp,">=")) return (s >= l)? 1:0;
  276. }
  277. //输出
  278. void output(FILE* fp,int flag,int n,char* name,char* litem,double sdata,char* comp,double ldata)
  279. {
  280.         if (flag)
  281.                 fprintf(fp,"%-d, %s, %s,%.5lf, %s,%.5lf, Pass,\r\n",n,name,litem,sdata,comp,ldata);        
  282.         else
  283.         {
  284.                 fprintf(fp,"%-d, %s, %s,%.5lf, %s,%.5lf, Fail,\r\n",n,name,litem,sdata,comp,ldata);
  285.                 ERROR++;
  286.         }
  287. }
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2