2010-08-01 33 views
0

这是跟我之前提出的问题以及在这里的一些人的帮助下的一个后续问题,我能够使用函数I想写,但我还没有完成它。 这是我早期的问题: 我有一系列带有扩展名(.msr)的文件,它们包含的测量数值超过十个参数,范围从日期,时间,温度,压力,......通过分号。数据值的例子如下所示。如何读取存储在一个目录中的不同文件,并将其中的一些数据存储到一个文件

2010-03-03 15:55:06; 8.01; 24.9; 14.52; 0.09; 84; 12.47; 
2010-03-03 15:55:10; 31.81; 24.9; 14.51; 0.08; 82; 12.40; 
2010-03-03 15:55:14; 45.19; 24.9; 14.52; 0.08; 86; 12.32; 
2010-03-03 15:55:17; 63.09; 24.9; 14.51; 0.07; 84; 12.24; 

每个文件都有一个名字REG_2010-03-03,REG_2010-03-04,REG_2010-03-05,......他们都包含在一个单一的文件。

  1. 我想从每个文件中提取的最新信息,在这种情况下,2010-03-03,第3列和列6
  2. 找到每3列和统计平均值6. 3.然后将结果存储在一个新文件中,该文件仅包含日期和上面列的计算平均值以供进一步分析。

我现在的问题: 我想打开包含30个扩展名为.msr的文件的目录。我想打开源文件,然后为其中的每个文件提取所需的信息,正如我前面所解释的那样,并且对于上面读取的每个文件来存储日期(每个文件中的统一)以及第3列和第6列的平均值在一个文件中。因此,目标文件将在每行中包含三列,即日期,平均值(第三列)和平均值(第六列),由空格分隔,使其总共为30行。以下是我开始使用的代码,并希望您的指南介绍如何实现此目标。

就像您上面所述。 这里是我想要实现的概要

1)打开包含文件的目录(这里是USB KEY)。 2)读取里面的所有msr文件名。 3)打开每个msr文件。 4)提取数据2(第6列的数据) 4)提取日期(它是文件中的第一列),忽略时间和分隔符( 5)提取数据1(第3列的数据) 6)提取数据2(第6列的数据) 7)计算第3列和第6列的平均值。 8)输出到文件(日期,意思是第3列,平均第6列) 9)关闭MSR文件 10)关闭该目录(如果可能)

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int file_getline_analyse(char *infile,char *outfile,char *path,char *strline) { 

int return_value=0; 

    FILE *fd=NULL; // pointer for data source 
    FILE *fo= NULL; // Destination file 
    char *file_path=NULL;  

    char *date, *tmp,*time; 
    double sum, mean = 0; 
    file_path=calloc((strlen(path)+strlen(infile)),sizeof(file_path)); 
    if (file_path==NULL) { 
     printf("file_path in get_line\n"); 
     exit(EXIT_FAILURE); 
    } 

    strcpy(file_path,path); // copies the path entered in the function call to the allocated meomory 
    strcat(file_path,infile); // concatenates the contents of the allocated meomory from the source file 

    fd=fopen(file_path,"r"); 

    fo = fopen(outfile, "w"); 

    if((fd==NULL) && (fo==NULL)) { 
     return_value = -1; 
    } 
    else { 
     int i=0; 
     int j=0; 
     while ((fgets (strline, BUFSIZ, fd))>0){ 
      date = strtok(strline, " "); 
      time=strtok(NULL, " "); // skip over time 
      tmp = strtok(NULL, ";"); 
      if (i == 3|| i == 6) { // get only the 3rd and 6th value 
       sum += strtod(tmp, NULL); 
       ++i; 
       if(j== '\n') { 
        // Replacing the characters at the end of the line by 0: 
        char *p = strchr (strline, '\n'); 
        if (p) { 
         *p = 0; 
        } 
        return_value = 0; 
        break; 

       } 
       j++; 


      } 

      mean = sum/(double)(j+1); 

      fprintf(fo,"%s: %.2f\n", date, mean); 

     } 
     fclose (fd); 
     fclose(fo); 
    } 

    free(file_path); 
    file_path=NULL; 

    return return_value; 
} 
+6

除非这是一个学习锻炼,有小于零的理由使用下了awk和Perl(尤其是)被设计来解决的任务。 – msw 2010-08-01 15:38:36

+0

您的文件如何“包含所有其他文件” - 它是一个zip,tar,rar还是其他内容?哪些列是3和6 - 是日期列0还是列1?你如何使结果“包含在每行三行” - 一行是一行,你的意思是列而不是行?至于msw问,为什么C为这个任务?如果它的功课标记为家庭作业,否则解释 - 在这方面不要羞愧,但否则最好的答案是“使用更合适的,更高级别的语言”(然后你就是否是perl,awk,python,ruby,或其他; - )... – 2010-08-01 15:47:24

+2

这通常是[R](http://www.r-project.org/)的一些东西。 – Wok 2010-08-01 15:51:12

回答

0

如果你不需要它是在C,我会选择另一种语言,例如Perl的:

sub analyze($) { 
    my ($fname) = @_; 
    my ($date, $sum3, $sum6, $n) = (undef, 0, 0, 0); 

    open(F, "<", $fname) or die "$fname: $!"; 
    while (defined(my $line = <F>)) { 
    my @words = split(m";", $line); 
    $date = split(" ", $words[0])[0]; # only use the date, not the time 
    $sum3 += $words[2]; 
    $sum6 += $words[5]; 
    $n++; 
    } 
    close(F) or die "$fname: $!"; 
    printf("%s;%f;%f\n", $date, $sum3/$n, $sum6/$n); 
} 

foreach my $fname (@ARGV) { 
    analyze($fname); 
} 

在C语言中,你缺少这种方便的功能,如:

  • 自动内存管理
  • 字符串容易的支持,例如拼接,分割
+0

谢谢罗兰,我完全理解你的观点,但重要的是,我正在使用它在已有的c项目中添加一些函数,因此它必须在c中。 实际上,有问题的文件在USB密钥中,所以我必须打开USB密钥目录,获取包含这些文件的目录,然后按照前面所述提取内容。就这样。 – chriscol 2010-08-02 10:17:54

相关问题