2011-05-09 114 views
1

我目前正在尝试从文件中扫描单行,但在字符串处遇到障碍。 这是我的教授告诉我要处理的示例行。从文件扫描

enum status{MEM,PREP,TRAV} 
union type { double int day, char* title, float cost} 

13953 P 12 26 2011 1 5 2012 2 A 3.30 249.00 A 2.0 148.00 MEM Cuba Christmas 3 0 2 Sierra Del Rosario, Cuba 

我很好,当我从文件中扫描它的时候接受的点(MEM古巴圣诞节)。我只是使用fscanf()来读取数据的第一部分,但是MEM是枚举类型,具有指定以下输入的联合类型。我的问题是扫描的语法。我试着从MEM开始使用getline,但是由于城市/国家可能有空间,所以我在标记化方面遇到了困难。不知道还有什么其他的扫描我正在看sscanf(),但不知道它是否适用于文件。

更新:

int main(void); 
{ 
int m, length = 100; 
char *word, file_name[100]; 
FILE *file_point 
printf("Please enter file name with .txt extension:"); 
scanf("%s", file_name); 
file_point = fopen(file_name,"r"); 

    while (fscanf(file_point, "%d", &m) != EOF) 
    { 

    temp.dest_code = m; 
    fscanf(file_point, " %c %d %d %d %d %d %d %d", 
    &temp.area_code, 
    &temp.Smonth, &temp.Sday, &temp.Syear, 
    &temp.Emonth, &temp.Eday, &temp.Eyear, 
    &temp.leg_num); 
    for (n=0; n < temp.leg_num; n++) 
    { 
     fscanf(file_point," %c %f %f", 
     &temp.tleg[n].travel_type, 
     &temp.tleg[n].travel_time, 
     &temp.tleg[n].cost); 
    } 
    fscanf(file_point," %d %d %d ", 
    &temp.adult, 
    &temp.child, 
    &temp.infant); 


    temp_name = (char *)malloc(length + 1); 
    getline (&temp_name, &length, file_point); 

    word = strtok(temp_name, ","); 

    temp.dest_name=(char *)malloc(strlen(word)+1); 
    strcpy(temp.dest_name, word); 

    word = strtok(NULL, ","); 

    temp.dest_country=(char *)malloc(strlen(word)+1); 
    strcpy(temp.dest_country,word2); 

    printf("name:%s country:%s\n", temp.dest_name, temp.dest_country); 
     printf("adult:%d , child:%d , infant:%d \n", temp.adult, temp.child, temp.infant); 

    } 
} 

这是我使用的基础,我想到了,但不知道如何处理枚举和工会的代码。我正在考虑做类似于:

getline(&status, &length, file_point); 

但我如何将字符串转换为整型或浮点型?

+0

哦,忘了提及我正在从一个文件中扫描此单行文件 – 2011-05-09 00:24:50

+0

您可以发布一些代码,向我们展示从现在开始您尝试做什么? – Heisenbug 2011-05-09 00:41:56

+0

'enum'最后需要一个分号。 'union'最后还需要一个分号,逗号需要是分号。但是,如果您已经编译了代码,那么问题在于您没有复制和粘贴代码。 – 2011-05-09 05:35:32

回答

2

如果我正确理解你的问题(我不确定我是否这么做),那么你面临的问题是在输入中看到'MEM'(或'PREP'或'TRAV')作为字符串,了解如何处理以下数据。 enum建议您可能需要将字符串MEM转换为枚举中的MEM值。

这种转换很难完全自动化。这将是简单简单到识别字符串,并决定基于字符串什么:

if (strcmp(found_string, "MEM") == 0) 
    ...do the MEM stuff... 
else if (strcmp(found_string, "PREP") == 0) 
    ...do the PREP stuff... 
else if (strcmp(found_string, "TRAV") == 0) 
    ...do the TRAV stuff... 
else 
    ...report unknown type code... 

但是,您可以创建从字符串处理转换为枚举值的结构。

struct StateConv 
{ 
    const char *string; 
    enum state number; 
}; 

static struct StateConv converter[] = 
{ 
    { "MEM", MEM }, 
    { "PREP", PREP }, 
    { "TRAV", TRAV }, 
}; 
enum { NUM_STATECONV = sizeof(converter)/sizeof(converter[0]) }; 

enum state state_conversion(const char *string) 
{ 
    for (int i = 0; i < NUM_STATECONV; i++) 
    { 
     if (strcmp(string, converter[i].string) == 0) 
      return(converter[i].number); 
    } 
    fprintf(stderr, "Failed to find conversion for %s\n", string); 
    exit(1); 
} 

您需要一个更好的错误处理策略,而不是'错误退出'。

您的扫描码需要读取该字,然后拨打state_conversion()。然后,根据您返回的内容,您可以以正确的方式读取您获得的状态的剩余(以下)数据。

+0

+1为清洁和完整的解决方案。 – Heisenbug 2011-05-09 05:56:18

+0

啊好吧我收到了很多错误,试图把它当作一个字符串 – 2011-05-09 13:53:47

1

不,你不能以你想要的方式做到这一点。你的文件中的MEM是一个字符串类型,你需要像解析一个字符串一样解析它,然后根据该字符串设置你的枚举值。 例如,当你要分析你的状态类型(MEM,PREP,TRAV):

char typeBuffer[6]; 
fscanf(file_point,"%5s",typeBuffer); 

然后手动比较typeBuffer的内容:

status stat; 
if (strcmp(typeBuffer, "MEM") == 0){ 
    stat = MEM; 
} 

字符串类型和枚举之间转换无法是隐含的。

+0

'typeBuffer'对于阅读'PREP'或'TRAV'来说太小了 - 你至少需要5个,并且可能更多允许错误。使用'“%5s”'和维度6并不是一个坏主意;允许您在不溢出变量的情况下拒绝“TRAVEL”。 – 2011-05-09 05:51:46

+0

@Jonathan Leffler:thanks..fixed – Heisenbug 2011-05-09 05:52:45

+0

你很快 - 我没有完成编辑我的评论。 – 2011-05-09 05:53:56