【问题标题】:Storing data in a program instead of in an external file将数据存储在程序中而不是外部文件中
【发布时间】:2011-09-03 13:56:48
【问题描述】:

我有以下 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 时,每个变量只显示一个值。

【问题讨论】:

  • 我不确定,我对此很迷茫进入程序?
  • ... q,q1,q2,ct,st,r2,r,d,ca,sa,aor,ar,br,bt,bp,bpp ... 拥有大量可笑的局部变量是不好的。为变量使用非常短的名称是不好的。两者兼得就是……(言语失败)

标签: c arrays string data-structures struct


【解决方案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 在未分配的内存上乱涂乱画。因此你的段错误。

【讨论】:

  • 这似乎非常适合我的使用,但是似乎只为 n、m、gnm 等的每个变量存储了最后一个数据条目。你有什么想法吗?在每次迭代中添加下一个数据点,而不是每次迭代都覆盖最后一个数据点?
  • @officerkrupke:这可能是因为你没有用你的真实代码替换/* Do whatever ... */ 注释。
  • 傻我!这似乎已经成功了!感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
相关资源
最近更新 更多