C语言 循环内/循环外数据的方差



我正在尝试编写一个程序,读取。pdb文件,这是在生物学应用程序中使用的文件类型。这种类型的文件具有标准格式,数据之间有不同的空白。文件的格式为

ATOM      4  N   ALA     1       2.670   1.801   1.072  0.00  0.00
ATOM      5  CA  ALA     1       3.225   3.144   1.197  0.00  0.00
ATOM      6  C   ALA     1       4.408   3.341   0.256  0.00  0.00
ATOM      7  O   ALA     1       4.553   4.394  -0.363  0.00  0.00
....      .  ..  ...     .       .....   .....   .....  ..... ....

所以我的程序(可能写得很糟糕)定义了一个结构,读入数据(我从另一个帖子中偷来的http://www.daniweb.com/software-development/c/threads/65455/reading-a-file-using-fscanf#),并将其存储到一个索引结构中。现在,如果我在内部if循环中打印这些值,它就会输出正确的数据。然而,当我在外部while循环外输出相同的值时,它给了我错误的atom[].name(恰好是HA,输入文件中数据的第三列中的最后一个值)。其他值都正确

这是我的程序

#include <stdio.h>
typedef struct 
{
   char *atm;
   int serial;
   char *name;
   char *resName;
   int resSeq;
   double x;
   double y;
   double z;
   double occupancy;
   double tempFactor;
} pdb;
int main(int argc, char** argv)
{
   int i, j;
   pdb atom[28]; 
   char atm[5]; 
   char name[3]; 
   char resName[4];
   int serial; 
   int resSeq;
   double x;
   double y;
   double z;
   double occupancy;
   double tempFactor;
   char buff[BUFSIZ];
   FILE *file = fopen("test.pdb", "r");
   i = 0;
   while (fgets(buff, sizeof buff, file) != NULL) 
   {
      if (sscanf(buff, "%s %d %s %s %d %lf %lf %lf %lf %lf", 
         atm, &serial, name, resName, &resSeq, &x, &y, &z, 
         &occupancy, &tempFactor) == 10)
      {
         atom[i].atm = atm;
         atom[i].serial = serial;
         atom[i].name = name;
         atom[i].resName = resName;
         atom[i].resSeq = resSeq;
         atom[i].x = x;
         atom[i].y = y;
         atom[i].z = z;
         atom[i].occupancy = occupancy;
         atom[i].tempFactor = tempFactor;
         i++;
         /*printf("%s ", atom[i].atm);
         printf("%d ", atom[i].serial);
         printf("%s ", atom[i].name);
         printf("%s ", atom[i].resName);
         printf("%d ", atom[i].resSeq);
         printf("%lf ", atom[i].x);
         printf("%lf ", atom[i].y);
         printf("%lf ", atom[i].z);
         printf("%lf ", atom[i].occupancy);
         printf("%lfn", atom[i].tempFactor);*/
      }
   }
   fclose(file);
   for (j = 0; j < i; j++)
      printf("%d of %d: %sn", j, i-1, atom[j].name);
   return(0);
}

知道为什么会这样吗?此外,任何关于程序格式/结构的帮助也将不胜感激。我更喜欢用Fortran,所以C结构不是我的专业范围。

提前感谢。

EDIT: jsn帮我解决了这个问题,Randy Howard对它进行了改进。以下是更新后的工作程序:

#include <stdio.h>
#include <stdlib.h>
typedef struct 
{
   char *atm;
   int serial;
   char *name;
   char *resName;
   int resSeq;
   double x;
   double y;
   double z;
   double occupancy;
   double tempFactor;
} pdb;
int main(int argc, char** argv)
{
   int i, j;
   pdb atom[28]; 
   int serial; 
   int resSeq;
   double x;
   double y;
   double z;
   double occupancy;
   double tempFactor;
   char buff[BUFSIZ];
   FILE *file = fopen("test.pdb", "r");
   i = 0;
   while (fgets(buff, sizeof buff, file) != NULL) 
   {
      char *atm = malloc(sizeof(char) * 5); 
      char *name = malloc(sizeof(char) * 3); 
      char *resName = malloc(sizeof(char) * 4); 
      if (sscanf(buff, "%s %d %s %s %d %lf %lf %lf %lf %lf", 
         atm, &serial, name, resName, &resSeq, &x, &y, &z, 
         &occupancy, &tempFactor) == 10)
      {
         atom[i].atm = atm;
         atom[i].serial = serial;
         atom[i].name = name;
         atom[i].resName = resName;
         atom[i].resSeq = resSeq;
         atom[i].x = x;
         atom[i].y = y;
         atom[i].z = z;
         atom[i].occupancy = occupancy;
         atom[i].tempFactor = tempFactor;
         i++;
      }
   }
   fclose(file);
   for (j = 0; j < i; j++)
   {
         printf("%s ", atom[j].atm);
         printf("%d ", atom[j].serial);
         printf("%s ", atom[j].name);
         printf("%s ", atom[j].resName);
         printf("%d ", atom[j].resSeq);
         printf("%lf ", atom[j].x);
         printf("%lf ", atom[j].y);
         printf("%lf ", atom[j].z);
         printf("%lf ", atom[j].occupancy);
         printf("%lfn", atom[j].tempFactor);
   }
   return(0);
}

在while循环中,您需要为每个名称的每个char*分配新的内存。您现在正在覆盖它们。

while (fgets(buff, sizeof buff, file) != NULL) 
{
    char *atm = malloc(sizeof(char) * 5); 
    char *name = malloc(sizeof(char) * 3); 
    char *resName = malloc(sizeof(char) * 4); 
    if (sscanf(buff, "%s %d %s %s %d %lf %lf %lf %lf %lf", 
             atm, &serial, name, resName, &resSeq, &x, &y, &z, 
             &occupancy, &tempFactor) == 10)

你正在复制char数组(指针),所以所有的名字应该是相同的(最后一个条目)。

最新更新