2013-02-28 55 views
1

這是一個C作業練習,它驅動着我的香蕉!我一直在研究它近兩天,還沒有得到它的工作,所以任何幫助mucho讚賞!逗號分隔的文本文件到結構數組

這裏的情景: 我有一個逗號分隔的文本文件,該文件是這樣的:

(2005 TS15),2013-Apr-07,15.2,0.0391,8.0,0.0205,20.61,20.61,1890,21,13,APO*,0.479,M 
(2010 GM23),2013-Apr-13,3.9,0.0099,0.9,0.0022,13.14,13.12,61600,24.7,7,APO*,0.195,M 
(2009 SQ104),2013-Apr-22,27.8,0.0714,27.8,0.0714,8.16,8.15,67300,20.9,19,APO*,0.408,S 
(2012 XF55),2013-Apr-22,32.7,0.0841,32.7,0.0840,7.33,7.33,15600,22.5,7,APO*,0.446,M 

有文件中(與近地球物體其數據)10000上下的記錄。

我需要能夠找到10個最大的對象/ 10個最接近的對象等,所以我的計劃是讀取數據到一個結構數組中,每個結構基於文件中的列。我已經創建了結構並創建了它的實例以從文件中填充。

我的問題是在一般功能在最後...我想...

我試過初始化結構的完整陣列的結構的一個空白實例,但沒有在那裏工作.. ..

我試着讀每行作爲一個字符串,然後基於「,」限制器令牌化它,但我無法計算如何保存令牌到結構的每個元素(這是結束部分哪被註釋掉......)

我試着用fread()把文件讀入結構數組中,但什麼都沒發生那裏要麼(這是註釋掉的結束部分...)

我的代碼如下。如果任何人都可以指引我正確的方向,我會非常感激! (我希望它格式化好的。如果我沒有解釋這個問題妥善讓我知道,我會!!!)

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

    #define RECORDS 10972 /* number of records in the file */ 

    typedef struct { 
     char *objectName; 
     char *CADate; 
     double NomDistLD; 
     double NomDistAU; 
     double MinDistLD; 
     double MinDistAU; 
     int VRel; 
     int Vinf; 
     int NSig; 
     float HVm; 
     int ref; 
     char *ObjClass; 
     double Diameter; 
     char *Type; 
    } NEO; 

    NEO textFile [RECORDS]; 
    NEO passing[RECORDS]; 


    void menu(); 
    void countFile (FILE*fptr); 
    void general (FILE*fptr); 


    int main (void) 
    { 
     char filename[50]; 
     int choice; 

     FILE* fptr; 

     printf("Enter name of file to open: \n"); 
     scanf("%s", &filename); 

     fptr = fopen(filename, "r"); 
     if (fptr != NULL) 
      printf ("File %s opened succesfully!\n\n", filename); 
     else 
      printf ("File %s not found!\n", filename); 

     countFile(fptr); 

     do 
     { 
    menu(); 
    choice= 0; 

     while(choice <1 || choice >5) 
     { 
      printf("\nChoose an option from the above (1-5):\n"); 
      scanf ("%d", &choice); 
     } 
      switch(choice) 
      { 
       case 1: 
        printf("function largest\n"); 
        break; 
       case 2: 
        printf("function closest\n"); 
        break; 
       case 3: 
        printf("function largest KE\n"); 
        break; 
       case 4: 
        general (fptr); 
        break; 
       default: 
        break; 
      } 
    } 

    while (choice !=5); 
     printf("\n\nProgram Exiting. Goodbye!\n\n"); 

fclose (fptr); 

return 0; 
    } 



    void general (FILE*fptr) 
    { 
int count= 0, fileEnd= 0, i= 0, test= 0; 
char **neoArray; 
char hold[200]; /* string to hold tokenised strings */ 
char temp[10000]; /* string to hold each record as it is read in */ 

char *pToken; 
const char *delim = ","; /* define delimiter to tokenising each record */ 

passing->objectName = ""; 
passing->CADate = ""; 
passing->NomDistLD = 0.0; 
passing->NomDistAU = 0.0; 
passing->MinDistLD = 0.0; 
passing->MinDistAU = 0.0; 
passing->VRel = 0; 
passing->Vinf = 0; 
passing->NSig = 0; 
passing->HVm = 0.0; 
passing->ref = 0; 
passing->ObjClass = ""; 
passing->Diameter = 0.0; 
passing->Type = ""; 


for (i=0; i<RECORDS; i++) 
{ 
    textFile[i] = passing; 
} 
    } 


     /* while (!feof(fptr)) 
{ 
    test = fread(&passing, sizeof(NEO), 1, fptr); 

    if(test != 0) 
    { 
     printf("\n%s %s %f\n", passing[0].objectName, passing[0].CADate, passing[0].NomDistLD); 
    } 
} 


/*while(!feof (fptr)) 
{ 
    for (i=0; i<RECORDS; i++) 
    { 

     fscanf(fptr, "%s", temp); 

     pToken = strtok(temp, delim); 
     { 
      strcpy(textFile[i].objectName, pToken); 
     } 

     pToken = strtok(NULL, delim); 
     while (pToken != NULL) 
     { 
      strcpy(textFile[i].CADate, pToken); 
     } 

     pToken = strtok(NULL, delim); 
     while (pToken != NULL) 
     { 
      textFile[i].NomDistLD = atoi(pToken); 
     } 

     printf("\n%s %s %f\n", textFile[i].objectName, textFile[i].CADate, textFile[i].NomDistLD); 
    } 

    rewind (fptr); 
} 
    } 
+1

您不能在結構中分配字符串,因此不能使用'strcpy'。你可以使用'strdup'來代替(即'textFile [i] .objectName = strdup(pToken);')你也不需要初始化數組,只需跟蹤加載條目的數量即可。 – 2013-02-28 15:24:12

+0

我想我實際上會哭...它似乎已經工作了!我的分配代碼(爲了更好地descritption的想要的)現在爲:而 \t { \t \t爲(I = 0;我<記錄;我++) \t \t { \t \t \t的fscanf(FEOF(FPTR)!) (fptr,「%s」,temp); \t \t \t \t \t \t pToken = strtok的(溫度,DELIM); \t \t \t { \t \t \t \t TEXTFILE [I] .objectName =的strdup(pToken); \t \t \t} \t \t \t pToken = strtok的(NULL,DELIM); \t \t \t { \t \t \t \t TEXTFILE [I] .CADate =的strdup(pToken); \t \t \t} \t \t \t pToken = strtok的(NULL,DELIM); \t \t \t { \t \t \t \t TEXTFILE [I] .NomDistLD = ATOF(pToken); \t \t \t} – FE21 2013-02-28 16:46:29

+0

所以,感謝Joachim提供的技巧! :) – FE21 2013-02-28 16:48:09

回答

1

你的問題很可能是複製串到內存隨機領域,因爲你從不初始化objectNameCADate指針。

你可能會更好過更換這些指針與數組實際:

char objectName[128]; 
char CADate[128]; 
+0

感謝放鬆(我與strdup一起,似乎已經工作!) – FE21 2013-02-28 16:49:37

1

我會在每一行

閱讀然後向前掃描直到找到。用\ 0替換每個。保持每個的計數,

使用計數來調用不同的sscanf函數來加載不同的字段到當前結構。字段的字符串類型需要調整,爲他們分配內存。

作爲一個快速測試具有CSV文件的一個較短的版本(比如4行),並使用斷言功能來檢查預期值漸入結構

這種問題更好地使用腳本完成perl或python語言

希望這有助於!

+0

感謝您的Vorsprung,我使用了一個測試文件,它使調試更容易(D'哦!)我使用strdup作爲約阿希姆建議,它似乎工作。 – FE21 2013-02-28 16:49:06

相關問題