看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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
firejox:http://codepad.org/L3DkCwjZ 寫的爛爛的code XD 07/18 20:11
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
firejox:http://codepad.org/rgefDG2P 07/18 21:49
tropical72:看 firejox code 是正確的選擇.我上述程式碼其實有很多 07/18 22:20
tropical72:錯,只是不寫程式碼我不會敘述 XD 07/18 22:21
firejox:改一下fpos_t http://codepad.org/1ORnq1nr 07/18 22:25
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