2013-04-02 55 views
1

我正試圖編寫一個讀取.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("%lf\n", atom[i].tempFactor);*/ 
     } 
    } 
    fclose(file); 
    for (j = 0; j < i; j++) 
     printf("%d of %d: %s\n", j, i-1, atom[j].name); 

    return(0); 
} 

任何想法,爲什麼這可能發生?此外,在節目格式/結構的任何幫助,也將不勝感激。我更多的是Fortran傢伙,所以C結構超出了我的專業領域。

提前致謝。

編輯: jsn幫助我和蘭迪霍華德完善它。這裏是更新和工作的程序:

#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("%lf\n", atom[j].tempFactor); 
    } 

    return(0); 
} 
+0

顯示一些預期的輸出。 –

+0

priti atom []。name(來自上面的輸入文件)應該產生N,CA,C,O,但產生HA,HA,HA,HA,這是輸入文件中該列的最後一個值。 – mjswartz

回答

2

在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數組(指針),因此所有名稱都應該相同(最後一個條目)。

+0

如果您的char *字段具有恆定的最大大小,您可以在結構中定義它們。例如'char name [3];'而不是'char * name;'。 – ehudt

+1

不要在C中轉換malloc。雖然,應該告訴OP,malloc需要stdlib.h。 –

+0

酷豆。非常感謝jsn,像魅力一樣工作! – mjswartz