在特定值的文件中定位

时间:2014-07-24 20:17:25

标签: c

我有一个C二进制文件,其中包含512个 3 值,其形式为三维立方体。我需要访问具有最高值的立方体中的位置,即密度。一旦我获得了最高值的位置,我需要在这个位置创建一个较小的3D立方体,其值明显小于512(立方体的尺寸)。 start表示较小立方体一角的位置。 p显然是二进制文件。

fseek(p,0,SEEK_END);
lSize = ftell(p);
rewind(p);

dim = pow(lSize/sizeof(float),1.0/3.0);
printf("File size: %lu bytes, Grid size: %d \n", lSize,(int)dim);

max = 0;
counter = 0;
index = 0;
while(fread(&density,sizeof(float),1,p),!feof(p) && !ferror(p)) {
  if(density > max) max = density,index = counter;
  counter += 1;
}

sub = 256;
start = index - (pow(dim,2)+dim+1)*(sub/2-1);
printf("3d coordinates of highest density: %lu,%lu,%lu, Dimension of cube: %d\n",index % 512;(index / 512) % 512;index / (512 * 512),(int)dim);

printf("The maximum density is: %e with index: %lu \n", max,index); 

rewind(p);
fseek(p,start*sizeof(float),SEEK_SET);
fseek(q,start*sizeof(float),SEEK_SET);
fseek(r,start*sizeof(float),SEEK_SET);
fseek(s,start*sizeof(float),SEEK_SET);
fseek(t,start*sizeof(float),SEEK_SET);

u = fopen("results_dens.dat", "w");
if (u == NULL) { printf("Unable to open output results file!"); exit(1); }

for (ibox=0;ibox<nbox;ibox++){
  for (k=0;k<nz[ibox];k++){
    fseek(p,(start+k*dim*dim)*sizeof(float),SEEK_SET);
    fseek(q,(start+k*dim*dim)*sizeof(float),SEEK_SET);
    fseek(r,(start+k*dim*dim)*sizeof(float),SEEK_SET);
    fseek(s,(start+k*dim*dim)*sizeof(float),SEEK_SET);
    fseek(t,(start+k*dim*dim)*sizeof(float),SEEK_SET);
    for (j=0;j<ny[ibox];j++){
      fseek(p,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
      fseek(q,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
      fseek(r,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
      fseek(s,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
      fseek(t,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
       for (i=0;i<nx[ibox];i++){

我知道上面的代码运行没有任何错误。但是,很多都依赖于index以上的价值。我不确定如何在C中定义位置。我知道这些是内存位置,但通过做一些粗略计算,我得到的索引值似乎接近框的边缘而不是中心。

512 3 = 134217728。 index的值是66978048,中间位置值为67108864,位置为130816.但是,130816大约为512 * 256,这意味着如果网格的中间位置位于框的边缘,那么{ {1}}以上。

1 个答案:

答案 0 :(得分:3)

也许这会有所帮助。首先,我使用以下程序创建了一个测试文件:

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

int makeCube(const char *fn, int dim)
{
    FILE *p;

    const int center = dim/2;
    p = fopen(fn,"w");
    for (int i=0; i < dim; ++i)
    for (int j=0; j < dim; ++j)
        for (int k=0; k < dim; ++k) {
            float f = dim - sqrtf(pow(i-center,2)+
                                  pow(j-center,2)+pow(k-center,2));
            fwrite(&f, sizeof(float), 1, p);
        }
    fclose(p);
    return 0;
}
int main() 
{
    const int dim = 512;
    makeCube("cube.bin", dim);
    return 0;
}

接下来,我重写了您的代码以获得正确的语法并打印一些看似有用的诊断:

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

int subCube(FILE *p, int dim)
{
    float density;
    float max = 0;
    long index = 0;
    long counter;

    for (counter=0; fread(&density,sizeof(float),1,p); ++counter) {
        if(density > max) {
            max = density;
            index = counter;
        }
    }

    printf("The maximum density is: %e with index: %lu \n", max,index); 
    int i = index/dim/dim;
    int j = (index - (i*dim*dim))/dim;
    int k = (index - ((i*dim)+j)*dim);
    printf("This corresponds to coordinates (%d,%d,%d)\n", i,j,k);
}

int main() 
{
    const int dim = 512;
    FILE *p = fopen("cube.bin","r");
    subCube(p, dim);
    fclose(p);
    return 0;
}

当我运行该程序时,我得到以下输出:

The maximum density is: 5.120000e+02 with index: 67240192 
This corresponds to coordinates (256,256,256)

由于测试数据基本上是中间密度最大的球体,因此完全符合预期。

请注意,由于错误处理,我玩得很快(没有!)但是为了清楚起见省略了它,而不是因为你应该在实际程序中省略它。