作者tropical72 (藍影)
看板C_and_CPP
標題Re: [問題] 讀檔問題
時間Mon Jul 18 18:09:32 2011
※ 引述《stanley0412 (逐夢)》之銘言:
恕刪.
原始碼我還真的沒留下來,我敘述概念在下面,這是「苦一次」、「爽以後」的做法.
-------
你資料的欄位: id score class gender behind meant blood
要關注的欄位: score meant
-------
變數說明
char** target_field : 輸入檔之欄位名稱
char** care_field : 你要關注的欄位名稱
unsigned field_cnt : 輸入檔實際上之欄位個數
unsigned care_field_cnt : 你要關注的欄位個數
-------
step 1 : 首先, 建立一個 set.dat ,裡面放你要關注欄位的字串抬頭,
並註明那欄的資料型態為何,我的假設只有三個,
0: string, 1: int , 2: floating , 要用數字還是字串都可議,
假設用數字, 長這樣
score 1
meant 1
-------------
step 2 : 程式剛開始時, 讀進來 set.dat, 並對字串做排序, 在做這個動作之前,
我會先讀 set.dat 裡面有幾行,
#1DyUBD7Q 這篇是我加速讀行數的方法,
讀行數的目的是為了要知道:「我有幾個欄位要關注」。
再來是動態配置一份記憶體出來
#define CHAR_CNT 30
unsigned care_field_cnt=0;
FILE *fp = fopen("set.dat", "r");
care_field_cnt = read_line_from_file(fp);
// 下面這二行是一個議題,更好的作法在
#1DdQmF0j
char **care_field = (char**)malloc( care_field_cnt );
for(i=0; i!=care_field_cnt; ++i) care_field[i]= (char*)malloc(CHAR_CNT);
int **care_field_style = (int*)malloc(care_field_cnt);
// 開始讀 set.dat 內容
fset(fp,0);
while(fscanf(fp, "%s%d", care_field[i], &care_field_style[i])!=EOF) ++i;
fclose(fp);
字串部份用 c++ string 會更漂亮處理, 重點是上面的包成 struct 會更好!
「但最好以 care_filed 為鍵值,同時對
care_field、care_field_style 做排序會是較好的選擇」
(所以才說包成 struct 會更好)
------------
step 3 : 一開始讀入輸入檔案 (假設 input.txt) 時,先 fgets 抬頭那行出來,
對 title 那行做分析, 共有幾個欄位
char buffer[2000], *ptr=NULL;
unsigned field_cnt=0;
FILE *fp = fopen("input.txt", "r");
// 算有幾個欄位
fgets(buffer, 2000, fp);
ptr = strtok(buffer, " "); // 可改用 strchr 可能更合適
while(ptr) ptr=strtok(NULL, " "), ++field_cnt;
--field_cnt; // 會多算一次
// 做記憶體配置
char **target_field = (char**)malloc(field_cnt);
for(i=0; i!=field_cnt; ++i) taget_field[i] = (char*)malloc(CHAR_CNT);
// 再次讀入
fset(fp, 0);
for(i=0; i!=field_cnt; ++i) fscanf(fp, "%s", target[i]);
------------
step 4 : 接著 step3, 依循讀入輸入檔時
while(fscanf(fp, "%s", buf)!=EOF){
for(i=0; i!=field_cnt; ++i) {
fscanf(fp, "%s", buf);
for(j=0; j!=care_field_cnt; ++j){
if(!strcmp(target[i], care_field[j])) {
if(care_field_style[j]==0) // 字串
else if(care_field_style[j]==1) // 整數, 做 atoi 後再處理
else if(care_field_style[j]==2) // 浮點數, 做 atof 後再處理
else // 其它處理
}
}
}
}
-----------
抱歉這陣子電腦中標, 那份 source code 沒留到,
但整體觀念大致如此, 但印象有包成 struct,
效率改善確實為另一個問題, (記得有用一點技巧去改善)
會研究一小段時間。
如果這種情形沒常發生的話, 改 source code 應會較方便。
---------
--
YouLoveMe() ? LetItBe() : LetMeFree();
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
→ firejox:你要不要用strspn判斷數字,浮點數,字串 07/18 18:16
→ tropical72:那可能會更方便,只是我記得我在真正做while讀取時, 07/18 18:20
→ tropical72:已經沒再做 !strcmp動作,有點像用bucket sort 方式直 07/18 18:20
→ tropical72:接索引進去,這部份我再想一下以前我怎麼做的. 07/18 18:21
推 stanley0412:謝謝t大 我在研究一下!!真的感恩O_Q!!! 07/18 19:01
→ tropical72:c 語言用很兇,希望你看得懂 XD. 07/18 19:02
推 KTFGU:推t大 07/18 19:57
→ tropical72:f 大太強了,這東西之前我做快一天.. 07/18 20:19
推 ericinttu: 我一天過後還在找資料 XDDD 07/18 20:42
推 stanley0412:我跟樓上一樣...到現在還在找資料... 07/18 20:45
→ stanley0412:謝謝f大.. 好恐怖.. 07/18 20:46
推 stanley0412:明天研究好了 今天不行了O_Q 07/18 20:48
推 ericinttu: 這樣聽起來感覺我好弱 〒△〒 〒△〒 07/18 20:53
→ firejox:唔...我嚇到人家了嗎.... 07/18 20:57
→ firejox:提醒:如果要存取int和double要轉型喔 07/18 20:57
推 KTFGU:決定了 這禮拜作業就是把 t大跟f大的code看懂~!XD 07/18 21:08
→ firejox:0_0 看t大的code就好了 我的很ugly.... 07/18 21:19
→ KTFGU: 沒關係 我也沒有多handsome 感謝你提供的code~ 07/18 21:27
→ firejox:突然想到 以KISS原則 用fpos_t比較簡單 07/18 21:48
→ tropical72:看 firejox code 是正確的選擇.我上述程式碼其實有很多 07/18 22:20
→ tropical72:錯,只是不寫程式碼我不會敘述 XD 07/18 22:21
推 gs1458:看了覺得自己弱到不行...囧 07/18 22:40
→ angleevil:firejox請問一下,當你算出row和col數量後,再次讀檔時 07/20 14:24
→ angleevil:field_type好像就沒用到呢? 07/20 14:25
→ angleevil:仔細看,其實也不用特地再範例使用ft.可以自己變更 07/20 14:53
→ firejox:0_0 其實只要能標示出型態 用什麼都可以 07/20 15:25
→ firejox:我用enum 只是複習一下而已... 07/20 15:26
→ firejox:而且你可以發覺我第二次讀的fscanf 是"%d" "%lf" "%s" XDD 07/20 15:27
→ angleevil:恩,謝謝分享<m.m> 07/20 15:44
→ tropical72:我覺得用 enum 確實較佳. 07/20 15:53
推 stanley0412:吸收到好多!!我真是學太少了!!再次感謝!!! 07/29 11:23