Re: [問題] 讀檔:檔案中某欄位有數字和字串

看板C_and_CPP作者 (不認識)時間14年前 (2011/10/27 21:01), 編輯推噓1(1038)
留言39則, 4人參與, 最新討論串2/2 (看更多)
先簡化我的輸入檔案(input.txt): Name Mike Sweep 5 Temp 20.1 各位好, 我想既然get_value裡的引述是寫死的, 我又知道key_name回傳的型別, 那何不定義三個get_value函數: string& Parameter::get_value_S(const key_type& key){ if(key=="Name"){ return Name; }else { std::cout << "No such a variable!" << std::endl; }//End if(key) }//End of const string& Parameter::get_value_S int& Parameter::get_value_I(const key_type& key){ if(key=="Sweep"){ return Sweep; }else { std::cout << "No such a variable!" << std::endl; }//End if(key) }//End of const int& Parameter::get_value_I double& Parameter::get_value_D(const key_type& key){ if(key=="Temp"){ return Temp; }else { std::cout << "No such a variable!" << std::endl; }//End if(key) }//End of const double& Parameter::get_value_D 讀檔時, 定義一個讀檔函數: Parameter &readinput(Parameter& parms){ std::string string1,string2; ifstream in("input.txt");//Initialize the constructor of in. ofstream out("output.txt"); if(!in) { cout << "Cannot open input file.\n"; } if(!out) { cout << "Cannot open output file.\n"; } while(in) { in >> string1>> string2; cout << string1 << " " << string2 <<std::endl; parms.read_value(string1,string2); }//End while in.close(); out.close(); return parms; }//End of Parameter& readinput(Parameter& parms) 其中的read_value()是類別Parameter裡的函數, 定義如下: void Parameter::read_value(const key_type& key,const key_type& key2){ if(key=="Name"){ std::cout<<"Inside read_value, Name="<<key2<<std::endl; Name=key2; }else if(key=="Temp"){ convertFromString(Temp,key2); std::cout<< "After converting: Temp" << Temp << endl; }else if(key=="Sweep"){ convertFromString(Sweep,key2); std::cout<< "After converting: Sweep" << Sweep << endl; }else { std::cout << "No such a variable!" << std::endl; // break; }//End if(key) }//End of Parameter::read_value(const key_type& key,const float& v) 其中的convertFromString定義如下: template <class T1> void convertFromString(T1 &value, const std::string &s) { std::stringstream ss(s); ss >> value;} 而類別Parameter宣告如下: class Parameter{ public: typedef std::string key_type; Parameter(){} ~Parameter(){} void read_value(const key_type&, const key_type&); string& get_value_S(const key_type&); int& get_value_I(const key_type&); double& get_value_D(const key_type&); private: int Sweep; double Temp; std::string Name; }; 在main函式裡, 就只定義物件parms和呼叫readinput()即可: Parameter parms; parms=readinput(parms); 如此, 在main裡可作測試: parms.get_value_I("Sweep")就得到整數5; parms.get_value_D("Temp")就得到double 20.1; parm.get_value_S("Name")就得到string Mike. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 134.76.93.247

10/27 21:06, , 1F
怎麼不用貼文章的網頁?
10/27 21:06, 1F

10/27 21:08, , 2F
我是這版的新手,沒用過也?建議哪種網頁呢?
10/27 21:08, 2F

10/27 21:09, , 3F
你這樣做就跟你的想法不一樣了啊,你這是固定回傳型
10/27 21:09, 3F

10/27 21:10, , 4F
態,但是你要求的是會自己變,這樣做的前提是你已經
10/27 21:10, 4F

10/27 21:10, , 5F
知道後面跟的值得型態,但如果這樣可以完成你的要求
10/27 21:10, 5F

10/27 21:10, , 6F
也不錯摟
10/27 21:10, 6F

10/27 21:11, , 7F
最下面就有公告了...
10/27 21:11, 7F

10/27 21:11, , 8F
第一個codepad是比較多人用的
10/27 21:11, 8F

10/27 21:13, , 9F
我就想說已知key_name,當然知它的回傳型態,固定義三個函數.
10/27 21:13, 9F

10/27 21:14, , 10F
好,感謝.以後我會用codepad的...
10/27 21:14, 10F

10/27 21:15, , 11F
這樣也滿不錯的,如果你用template可以把三個簡化
10/27 21:15, 11F

10/27 21:15, , 12F
成一個
10/27 21:15, 12F

10/27 21:15, , 13F
類似convertFromString那個,把回傳質改成參照
10/27 21:15, 13F

10/27 21:16, , 14F
不行耶,我的Parameter類別不是模板類別,C++無法接受在裡面
10/27 21:16, 14F

10/27 21:16, , 15F
定義一個模板函數.
10/27 21:16, 15F

10/27 21:17, , 16F
只是這樣就會多存一個值在外部
10/27 21:17, 16F

10/27 21:20, , 17F
能不能用template跟class無關啊
10/27 21:20, 17F

10/27 21:20, , 18F

10/27 21:21, , 19F
加上return只是為了配合cout...
10/27 21:21, 19F

10/27 21:21, , 20F
...我在上一篇推辛酸的
10/27 21:21, 20F

10/27 21:24, , 21F
tuple高招...y
10/27 21:24, 21F

10/27 21:25, , 22F
poyenc大使用了boost算是進階的作法,感謝你讓我學習摟...
10/27 21:25, 22F

10/27 21:26, , 23F
好,我測試一下template....
10/27 21:26, 23F

10/27 21:32, , 24F
我知道為什麼不行了,因為若用template <class T>,
10/27 21:32, 24F

10/27 21:34, , 25F
T& get_value(const std::string); 在呼叫時裡面的參數都是
10/27 21:34, 25F

10/27 21:35, , 26F
string,故編譯失敗.d大的例子是有不同的型態a
10/27 21:35, 26F

10/27 21:57, , 27F
標準就有tuple了
10/27 21:57, 27F

10/27 22:06, , 28F
要先用不同型態去觸發T,才能夠替換掉T
10/27 22:06, 28F

10/27 22:10, , 29F
可否用兩個引數:T& get_value(const std::string,T).呼叫時
10/27 22:10, 29F

10/27 22:11, , 30F
都可以,只要記得替換就好,template用兩個也可以
10/27 22:11, 30F

10/27 22:11, , 31F
parms.get_value("Name",a)可得Mike;改成("Temp",1.)得20.1
10/27 22:11, 31F

10/27 22:21, , 32F
只要把固定型態的放到那個參數,就會自己把T取代
10/27 22:21, 32F

10/27 22:32, , 33F
T Parameter::get_value(const key_type& key,T a)無法成功
10/27 22:32, 33F

10/27 22:32, , 34F
could not convert ‘((Parameter*)this)->Parameter::Temp
10/27 22:32, 34F

10/27 22:33, , 35F
’ from ‘double’ to ‘std::basic_string<char>’
10/27 22:33, 35F

10/28 00:11, , 36F
他已經說出重點了,double不能轉型成string
10/28 00:11, 36F

10/28 20:08, , 37F
可以讓它不要字串是字串嗎= =... 假如不是字串判別...
10/28 20:08, 37F

10/28 20:09, , 38F
就可以用macro了呀....
10/28 20:09, 38F

10/28 20:10, , 39F
囧 重複了"字串"一次...
10/28 20:10, 39F
文章代碼(AID): #1EgLOizT (C_and_CPP)
文章代碼(AID): #1EgLOizT (C_and_CPP)