2011-05-09 212 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