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

相关问题