2013-01-24 51 views
1

我目前正在编写一些代码,到目前为止,一切都编译好。代码的目的是这样的:外部函数不工作 - 但不知道为什么

  • 从数据文件读取输入并将值分配给数组。
  • “平滑数据”是通过取给定间隔的数据平均值,并用该平均值替换该间隔中的每个值。

这是导致我陷入困境的第二部分。在外部函数,由于某种原因,它工作时,我的“for”循环是这样的:

for(i=t; i<t+z; i++) 

但我不希望它这样做。我想要它这样做:

for(i=t*z; i<(t+1)*z; i++) 

当我尝试编译时,它只是崩溃了我。任何人都知道原因?现在几个小时我一直困惑着我。所有代码如下所示:

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

float foo(float*, int, int); 

int main(int argc, char* argv[]) 
{ 
    FILE *input; 

    const char datafile[]="datainput.dat"; 
    input=fopen(datafile, "r"); 

    int i; 
    int N=0, t=0; 
    int z=100; 
    int M=10; 
    float *a, avg; 

    a=(float*)malloc(M*sizeof(float)); 

    if((input!=(FILE*) NULL)) 
    { 
     while(fscanf(input, "%e", &a[t++])==1) 
     { 
      if (t>=M) 
      { 
       M*=2; 
       a=(float *)realloc(a, M*sizeof(float)); 
      } 
      N++; 
     } 
     float u[N]; 

     for(t=0; t<N; t++) 
     { 
      avg = foo(a, z, t); 
      u[t] = avg; 
     } 
     fclose(input); 
    } 
    else 
     printf("Input file could not be opened.\n"); 

    return(0); 
} 

float foo(float b[], int z, int t) 
{ 
    int i; 
    int k=0; 
    float avg; 
    float sum=0; 

    for(i=t*z; i<(t+1)*z; i++) 
    { 
     sum+=b[i]; 
     k++; 
    } 
    avg = sum/(float)k; 

    return(avg); 
} 

注意:你可能会注意到在代码中定义float u [N]的糟糕做法。我不太喜欢这种存在,但是你会注意到N是一个变量,用于统计输入文件中的数值(最初是未知的),并且初始化设置为N = 0,所以我不确定如何我解决了这个问题。

此外,我在这里提出了这个问题,但我的realloc没有任何条款,如果它失败。这是我正在努力,但目前它编译没有它在那里。

此外,所有数据值的形式都是浮点数,小数点后七位,以科学计数法表示,因此%e。

谢谢!


编辑:这里是一些来自数据文件的值。即使左边的值有序,它们也是文件中的实际值,而不是表示右边的值。

8.0800000e+00 7.0872796e-01 
    8.0900000e+00 7.1941101e-01 
    8.1000000e+00 2.1635408e+00 
    8.1100000e+00 -5.4200807e-01 
    8.1200000e+00 1.1046968e+00 
    8.1300000e+00 1.5833782e+00 
    8.1400000e+00 6.6122899e-01 
    8.1500000e+00 1.7922273e+00 
    8.1600000e+00 1.2446803e+00 
    8.1700000e+00 3.7869871e-01 
    8.1800000e+00 1.4793635e+00 
    8.1900000e+00 1.0508171e+00 
    8.2000000e+00 9.1012735e-01 
    8.2100000e+00 6.0967729e-01 
    8.2200000e+00 1.3834455e+00 
    8.2300000e+00 -5.2312924e-01 
    8.2400000e+00 9.2566688e-01 
    8.2500000e+00 7.8145188e-01 
    8.2600000e+00 4.1410150e-01 
    8.2700000e+00 1.9796986e+00 
    8.2800000e+00 5.9372874e-01 
    8.2900000e+00 1.8696331e+00 
    8.3000000e+00 2.3058409e+00 
+0

它如何崩溃?分段错误?如果是这样,你是否尝试通过'gdb'来查看哪条线导致崩溃? –

+0

什么是错误,以及在哪一行?你也可能想让你的变量名更有意义。 – OldProgrammer

+0

我目前正在使用Codeblocks,当我尝试运行它时,它说file.exe已停止工作(如在Windows上没有响应时)。 – user1988898

回答

1

所以我一直在盯着这一段时间。这是我想出的。间隔(我假设是100)。为了理智,我将它更改为5,后面的代码是因为您的示例发布数据只有46个元素。我必须假设你的是很多大于这个。

需要注意以下几点:

  • foo()不再依赖于一些怪诞的“我在哪里我的计算平均”的变量。 调用者负责将元素的起始位置和数量传递给平均值。如您所见,这使得代码更简单。这基本上是问题的核心,因为你的分配循环很好(除非没有检查你的realloc返回值)。没有理由使该函数复杂化,试图计算某个更大阵列中某处的平均值。把事情简单化。只需要调用者告诉函数从哪里开始以及要平均多少。

  • 虽然没有指定,我相信z是你的“间隔”宽度。下面代码中要注意的是间隔计数计算。间隔的数量仅为(N+(z-1))/z,这将导致需要处理的间隔数量,包括最后一个间隔可能只是一个部分。从那里开始,我们只需遍历原始数组,在z大小的切片中进行分割,计算平均值,然后重写刚才用相同平均值平均的区间。最后的时间间隔也可以是局部的,这需要一点额外的注意。

  • 我将数据文件更改为命令行参数argv[1]。让我更容易测试。

当然希望这是你要找的。 Thx为乐趣,并且不要忘记将此代码中的z值重置为100,如果您打算使用它。

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

float foo(float a[], int count); 

int main(int argc, char* argv[]) 
{ 
    if (argc !=2) 
     return EXIT_FAILURE; 

    FILE *input=fopen(argv[1], "r"); 
    if (input != NULL) 
    { 
     int z=5,t=0; 
     int M=10,N=0; 
     float *a = malloc(M*sizeof(float)); 

     while(fscanf(input, " %e", a + N) ==1) 
     { 
      if (++N>=M) 
      { 
       void *tmp = realloc(a, (M*=2)*sizeof(float)); 
       if (tmp != NULL) 
       { 
        a = tmp; 
       } 
       else 
       { 
        perror("Failed to allocate memory."); 
        exit(EXIT_FAILURE); 
       } 
      } 
     } 

     // compute number of intervals we will process. the last 
     // interval may be only a partial. 
     for (t=0;t<N;t+=z) 
     { 
      // how many we're doing in this interval 
      int count = (z < (N-t) ? z : (N-t)), k=0; 
      float avg = foo(a+t, count); 
      printf("Avg[%d] = %e\n", t/z, avg); 

      // smooth over original array with just-found svg. 
      for (k=0;k<count; a[t+k++] = avg); 
     } 
     fclose(input); 

     // dump the final array content 
     for (t=0;t<N;++t) 
      printf("a[%d] = %e\n", t, a[t]); 

     // release original array. 
     free(a); 
    } 
    else 
    { 
     perror("Input file could not be opened."); 
    } 

    return(0); 
} 
// find the average of the range of floats we're given. 
float foo(float a[], int count) 
{ 
    float sum = 0; 
    int i = 0; 

    for(i=0; i<count; sum += a[i++]); 
    return (sum)/(float)(count); 
} 

输出(Z = 5)

Avg[0] = 5.139628e+00 
Avg[1] = 3.791246e+00 
Avg[2] = 5.332921e+00 
Avg[3] = 3.949121e+00 
Avg[4] = 5.420036e+00 
Avg[5] = 3.866650e+00 
Avg[6] = 5.024508e+00 
Avg[7] = 3.941051e+00 
Avg[8] = 5.466672e+00 
Avg[9] = 2.305841e+00 
a[0] = 5.139628e+00 
a[1] = 5.139628e+00 
a[2] = 5.139628e+00 
a[3] = 5.139628e+00 
a[4] = 5.139628e+00 
a[5] = 3.791246e+00 
a[6] = 3.791246e+00 
a[7] = 3.791246e+00 
a[8] = 3.791246e+00 
a[9] = 3.791246e+00 
a[10] = 5.332921e+00 
a[11] = 5.332921e+00 
a[12] = 5.332921e+00 
a[13] = 5.332921e+00 
a[14] = 5.332921e+00 
a[15] = 3.949121e+00 
a[16] = 3.949121e+00 
a[17] = 3.949121e+00 
a[18] = 3.949121e+00 
a[19] = 3.949121e+00 
a[20] = 5.420036e+00 
a[21] = 5.420036e+00 
a[22] = 5.420036e+00 
a[23] = 5.420036e+00 
a[24] = 5.420036e+00 
a[25] = 3.866650e+00 
a[26] = 3.866650e+00 
a[27] = 3.866650e+00 
a[28] = 3.866650e+00 
a[29] = 3.866650e+00 
a[30] = 5.024508e+00 
a[31] = 5.024508e+00 
a[32] = 5.024508e+00 
a[33] = 5.024508e+00 
a[34] = 5.024508e+00 
a[35] = 3.941051e+00 
a[36] = 3.941051e+00 
a[37] = 3.941051e+00 
a[38] = 3.941051e+00 
a[39] = 3.941051e+00 
a[40] = 5.466672e+00 
a[41] = 5.466672e+00 
a[42] = 5.466672e+00 
a[43] = 5.466672e+00 
a[44] = 5.466672e+00 
a[45] = 2.305841e+00 

输出(Z = 10)

Avg[0] = 4.465437e+00 
Avg[1] = 4.641021e+00 
Avg[2] = 4.643343e+00 
Avg[3] = 4.482779e+00 
Avg[4] = 4.939867e+00 
a[0] = 4.465437e+00 
a[1] = 4.465437e+00 
a[2] = 4.465437e+00 
a[3] = 4.465437e+00 
a[4] = 4.465437e+00 
a[5] = 4.465437e+00 
a[6] = 4.465437e+00 
a[7] = 4.465437e+00 
a[8] = 4.465437e+00 
a[9] = 4.465437e+00 
a[10] = 4.641021e+00 
a[11] = 4.641021e+00 
a[12] = 4.641021e+00 
a[13] = 4.641021e+00 
a[14] = 4.641021e+00 
a[15] = 4.641021e+00 
a[16] = 4.641021e+00 
a[17] = 4.641021e+00 
a[18] = 4.641021e+00 
a[19] = 4.641021e+00 
a[20] = 4.643343e+00 
a[21] = 4.643343e+00 
a[22] = 4.643343e+00 
a[23] = 4.643343e+00 
a[24] = 4.643343e+00 
a[25] = 4.643343e+00 
a[26] = 4.643343e+00 
a[27] = 4.643343e+00 
a[28] = 4.643343e+00 
a[29] = 4.643343e+00 
a[30] = 4.482779e+00 
a[31] = 4.482779e+00 
a[32] = 4.482779e+00 
a[33] = 4.482779e+00 
a[34] = 4.482779e+00 
a[35] = 4.482779e+00 
a[36] = 4.482779e+00 
a[37] = 4.482779e+00 
a[38] = 4.482779e+00 
a[39] = 4.482779e+00 
a[40] = 4.939867e+00 
a[41] = 4.939867e+00 
a[42] = 4.939867e+00 
a[43] = 4.939867e+00 
a[44] = 4.939867e+00 
a[45] = 4.939867e+00 
+0

非常感谢你。我只希望推动正确的方向,所以你给一个替代版本是太棒了。我明白你所拥有的大部分;我似乎有一个问题(编译时)是检查realloc的返回值。它似乎阻止我打印任何东西,而是返回1(这是在CodeBlocks上)。你有什么想法,为什么这个?这是我没有将它列入首位的原因之一,因为我能够在不存在的情况下打印输出。 – user1988898

+0

return(1)表示EXIT_FAILURE,这不好。你在谈论while循环中的'realloc()',对吧?不是最初的那个('malloc()')?哦,再次检查代码,我不小心在'if()'中与M进行比较。现在在发布的代码中。 – WhozCraig

+0

其实等一下。只是试了一遍,它的工作原理。 – user1988898

0

它不太可能sum+=b[i];将访问数组b 0至N-1。

0

您已经为函数的数组参数传递了10个用于浮点数的块。在语句sum + = b [i]中,这里b [i]不能确保你不是指向数组大小的索引,因为你的“i”可能超过10当z = 100和t = 1时。

相关问题