将数据存储在程序中而不是外部文件中

时间:2011-05-27 17:20:25

标签: c arrays string data-structures struct

我有以下 C 代码的一部分,它使用来自文件名WMM.COF的数据,并使用存储在文件中的数据来计算地球的磁场。程序运行正常,但我不能让程序访问外部文件;我想将所有数据都存储在程序中。我尝试使用结构数组来复制数据,然后将数组放入一个字符串,但这会导致程序出错并且不会产生正确的结果。这是我正在尝试修改的程序代码。

static void E0000(int IENTRY, int *maxdeg, double alt, double glat, double glon, double time, double *dec, double *dip, double *ti, double *gv)
{
  static int maxord,i,icomp,n,m,j,D1,D2,D3,D4;
  static double c[13][13],cd[13][13],tc[13][13],dp[13][13],snorm[169],
    sp[13],cp[13],fn[13],fm[13],pp[13],k[13][13],pi,dtr,a,b,re,
    a2,b2,c2,a4,b4,c4,epoch,gnm,hnm,dgnm,dhnm,flnmj,otime,oalt,
    olat,olon,dt,rlon,rlat,srlon,srlat,crlon,crlat,srlat2,
    crlat2,q,q1,q2,ct,st,r2,r,d,ca,sa,aor,ar,br,bt,bp,bpp,
    par,temp1,temp2,parp,bx,by,bz,bh;
  static char model[20], c_str[81], c_new[5];
  static double *p = snorm;
  char answer;

  FILE *wmmdat;


  wmmdat = fopen("WMM.COF","r");

/* INITIALIZE CONSTANTS */
  maxord = *maxdeg;
  sp[0] = 0.0;
  cp[0] = *p = pp[0] = 1.0;
  dp[0][0] = 0.0;
  a = 6378.137;
  b = 6356.7523142;
  re = 6371.2;
  a2 = a*a;
  b2 = b*b;
  c2 = a2-b2;
  a4 = a2*a2;
  b4 = b2*b2;
  c4 = a4 - b4;

/* READ WORLD MAGNETIC MODEL SPHERICAL HARMONIC COEFFICIENTS */
  c[0][0] = 0.0;
  cd[0][0] = 0.0;

  fgets(c_str, 80, wmmdat);


 S3:
  if (fgets(c_str, 80, wmmdat) == NULL) goto S4;

/* CHECK FOR LAST LINE IN FILE */
  for (i=0; i<4 && (c_str[i] != '\0'); i++)
    {
      c_new[i] = c_str[i];
      c_new[i+1] = '\0';
    }
  icomp = strcmp("9999", c_new);
  if (icomp == 0) goto S4;
/* END OF FILE NOT ENCOUNTERED, GET VALUES */
sscanf(c_str,"%d%d%lf%lf%lf%lf",&n,&m,&gnm,&hnm,&dgnm,&dhnm);

  if (n > maxord) goto S4;
  if (m > n || m < 0.0) 
    {
      fprintf(stderr, "Corrupt record in model file WMM.COF\n");
      exit(1);
    }

  if (m <= n)
    {
      c[m][n] = gnm;
      cd[m][n] = dgnm;
      if (m != 0)
        {
          c[n][m-1] = hnm;
          cd[n][m-1] = dhnm;
        }
    }
  goto S3;

/* CONVERT SCHMIDT NORMALIZED GAUSS COEFFICIENTS TO UNNORMALIZED */
 S4:
  *snorm = 1.0;
  fm[0] = 0.0;
  for (n=1; n<=maxord; n++)
    {
      *(snorm+n) = *(snorm+n-1)*(double)(2*n-1)/(double)n;
      j = 2;
      for (m=0,D1=1,D2=(n-m+D1)/D1; D2>0; D2--,m+=D1)
        {
          k[m][n] = (double)(((n-1)*(n-1))-(m*m))/(double)((2*n-1)*(2*n-3));
          if (m > 0)
            {
              flnmj = (double)((n-m+1)*j)/(double)(n+m);
              *(snorm+n+m*13) = *(snorm+n+(m-1)*13)*sqrt(flnmj);
              j = 1;
              c[n][m-1] = *(snorm+n+m*13)*c[n][m-1];
              cd[n][m-1] = *(snorm+n+m*13)*cd[n][m-1];
            }
          c[m][n] = *(snorm+n+m*13)*c[m][n];
          cd[m][n] = *(snorm+n+m*13)*cd[m][n];
        }
      fn[n] = (double)(n+1);
      fm[n] = (double)n;
    }
  k[1][1] = 0.0;

  otime = oalt = olat = olon = -1000.0;
  fclose(wmmdat);
  return;

我想出的将程序中的数据包含在内的代码如下:

    struct wmm
       {
        int   alpha;
        int   beta;
        float gamma;
        float delta;
        float epsilon;
        float zeta;
       }book[90]= {{1, 0, -29496.6, 0.0, 11.6,  0.0},
  {1, 1,  -1586.3,    4944.4,       16.5,     -25.9},
  {2, 0,  -2396.6,       0.0,      -12.1,       0.0},
  {2, 1,   3026.1,   -2707.7,       -4.4,     -22.5},
  {2, 2,   1668.6,    -576.1,        1.9,     -11.8},
  {3, 0,   1340.1,       0.0,        0.4,       0.0},
  /* 50+ similar lines of code */
 {12,  8,    -0.4,       0.1,        0.0,        0.0},
 {12,  9,    -0.4,       0.3,        0.0,        0.0},
 {12, 10,     0.2,      -0.9,        0.0,        0.0},
 {12, 11,    -0.8,      -0.2,       -0.1,        0.0},
 {12, 12,     0.0,       0.9,        0.1,        0.0}};





for (i = 0; i < 90 && offset < buf_size; i++) 
    {
     offset += snprintf(c_str + offset,buf_size - offset, "%d %d %7.1lf %7.1lf %7.1lf %7.1lf \n", book[i].alpha, book[i].beta , book[i].gamma , book[i].delta, book[i].epsilon, book[i].zeta);
     }


     sscanf(c_str,"%d%d%lf%lf%lf%lf",&n,&m,&gnm,&hnm,&dgnm,&dhnm);  

问题是snprintf导致程序在每次放入程序时冻结并终止。当我编写的代码在它自己运行时,它似乎正确地创建c_str,除非我尝试查看变量n,m,gnm,hnm,dgnm和dhnm时,只显示每个变量的单个值。

1 个答案:

答案 0 :(得分:1)

由于评论中缺少空格/格式,我需要继续回答。

首先,你有90个条目,但你可以让编译器弄清楚book数组需要多少条目:

struct wmm {
    int   alpha;
    int   beta;
    float gamma;
    float delta;
    float epsilon;
    float zeta;
} book[] = {
    {1,   0, -29496.6,    0.0, 11.6,   0.0},
    {1,   1,  -1586.3, 4944.4, 16.5, -25.9},
    /* ... */
    {12, 12,      0.0,    0.9,  0.1,   0.0}
};

而且,更重要的是,你不需要将它们放在一个字符串中,并在你手头有它们时将它们拉回来:

for(i = 0; i < sizeof(book)/sizeof(book[0]); ++i) {
    n    = book[i].alpha;
    m    = book[i].beta;
    gnm  = book[i].gamma;
    hnm  = book[i].delta;
    dgnm = book[i].epsilon;
    dhnm = book[i].zeta;
    /* Do whatever you need to do with the above variables. */
}

对于您snprintf所造成的缓冲区溢出,这将是一个整齐的步骤。

您的c_str仅为char[81],您每次都会循环90次,并将偏移量增加到c_str;所以,你不久就会跑到c_str的末尾,然后你会告诉snprintf乱写未分配的内存。因此你的段错误。