歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

在C++ Builder 和GCC(MinGW)中讀寫數據文件的類

常常在GCC(MinGW)和C++ Builder 中都有讀寫數據的時候,也就是從文件中將一組數據讀入二維數組<vector>,或者將數組中的數據格式化寫入文件,甚至有時還想給文件加個文件頭,當然文件頭也要對齊了才好看一點,兩個軟件實現的方法都不一樣,常常讓人惱火,今天有空,編寫了個類,兩個都能通用的文件讀寫類FileData.

有3點請大家注意:

1.FileData類讀的數據文件的格式是任意的,數據的排列方式也是任意的,

也就是說FileData可以自動檢測數據的排列方式和分割方式,每行的數據個數可以互不相同!

一句話,只要文件裡面有數據就可以正確識別!

2.FileData將數組和文件頭寫入文件的時候,自動對齊數據和文件頭.

也就是說你用記事本打開一看,數據和文件頭是排列得整整齊齊的.

3.FileData中使用了寬字符(漢字),所以為了讓MinGW識別,請將FileData.hpp保存為UTF-8的格式.

  1. // -----------------------------------------------------------------------------   
  2. // 功能強大的讀寫數據文件類 FileData.hpp   
  3. // 經常要將數據導入C++,使用這個很方便   
  4. // Wu Xuping 2012-02-09   
  5. // 測試環境:   
  6. // C++ builder 2010   
  7. // MinGW 4.5.1 windows   
  8. // www.linuxidc.com
  9. // 使用很簡單,看看最後附上的測試代碼即可   
  10. // FileData.hpp一定要保存為UTF-8的格式,因為這是MinGW的默認格式   
  11. // -----------------------------------------------------------------------------   
  12. #ifndef FileData_H   
  13. #define FileData_H   
  14. // --------------------   
  15. #include <iostream>   
  16. #include <fstream>   
  17. #include <vector>   
  18. #include <string>   
  19. #include <sstream>   
  20. #include <iterator>   
  21. #include <algorithm>   
  22. using namespace std;  
  23.   
  24. // ==============================================================================   
  25. // SplitString::分割字符串的函數   
  26. // ==============================================================================   
  27. // -----------------------------------------------------------------------------   
  28. void SplitString(string str, vector<string>&sv, string separator = " ;,\t") {  
  29.     // ---------------------------------------   
  30.     if (sv.size() > 0) {  
  31.         sv.clear();  
  32.     }  
  33.     // ---------------------------------------   
  34.     vector<long int>index_v; // 分割索引   
  35.     // ---------------------------------------   
  36.     for (unsigned i = 0; i < str.length(); i++) {  
  37.         for (unsigned j = 0; j < separator.length(); j++) {  
  38.             if (str[i] == separator[j]) {  
  39.                 index_v.push_back(i);  
  40.             }  
  41.         }  
  42.     }  
  43.     // ---------------------------------   
  44.     index_v.push_back(-1); // 加上開始的字符   
  45.     index_v.push_back(str.length()); // 加上結尾的字符   
  46.     // -----------------------------------   
  47.     sort(index_v.begin(), index_v.end()); // 排序   
  48.     // --------------------------------   
  49.     for (unsigned i = 1; i < index_v.size(); i++) {  
  50.         long int startindex = index_v[i - 1] + 1;  
  51.         long int endindex = index_v[i];  
  52.         if (startindex < endindex) {  
  53.             string cstr(str.begin() + startindex, str.begin() + endindex);  
  54.             sv.push_back(cstr);  
  55.         }  
  56.     };  
  57.     // --------------------------------   
  58. };  
  59. // -----------------------------------------------------   
  60.   
  61. // ==============================================================================   
  62. // StringToDoubleVector::將字符串轉換為數組的函數   
  63. // ==============================================================================   
  64. void StringToDoubleVector(string istr, vector<double> &od1v) {  
  65.     if (od1v.size() > 0) {  
  66.         od1v.clear();  
  67.     }  
  68.     // 將不要的字符的字符全部換成空格,   
  69.     string delimit = " ";  
  70.     for (string::size_type i = 0; i < istr.length(); i++) {  
  71.         int si = char(istr[i]);  
  72.         if (si < 43 || si > 57 || si == 44 || si == 47) {  
  73.             if (si != 100 && si != 101 && si != 68 && si != 69) {  
  74.                 // 不是dD或eE的字符都用空格代替   
  75.                 istr.erase(i, 1);  
  76.                 istr.insert(i, delimit);  
  77.             }  
  78.         }  
  79.     }  
  80.     // -------分割字符串   
  81.     vector<string>vs;  
  82.   
  83.     for (string::size_type i = 0; i < istr.length(); i++) {  
  84.         if (istr[i] == delimit[0]) {  
  85.             string cstr = istr.substr(0, i);  
  86.             vs.push_back(cstr);  
  87.             istr.erase(0, i);  
  88.             i = 0;  
  89.         }  
  90.     }  
  91.     vs.push_back(istr);  
  92.     // -----------字符轉為double類型的數   
  93.     for (unsigned int i = 0; i < vs.size(); i++) {  
  94.         istr = vs[i];  
  95.         istringstream istr_stream(istr);  
  96.         double num;  
  97.         while (istr_stream >> num) {  
  98.             od1v.push_back(num);  
  99.         }  
  100.     }  
  101.   
  102. };  
  103.   
  104. // -----------------------------------------------------------------------------   
  105. // FileData::讀寫文件的類   
  106. // -----------------------------------------------------------------------------   
  107. class FileData {  
  108. private:  
  109.     vector<vector<double> >_Data; // 二維數組   
  110.   
  111.     unsigned int _Row; // 數組的行數   
  112.     unsigned int _MinColumn; // 數組最小列   
  113.     unsigned int _MaxColumn; // 數組最大列   
  114.   
  115.     string _FileName; // 文件名   
  116.     string _Headstr; // 文件第一行字符串   
  117.   
  118.     // -讀寫文件中的數據-----------------------------------------------   
  119.     void LoadDataFromFile();  
  120.     void SaveDataToFile();  
  121.     // -----------------------------------------------------------------   
  122.   
  123. public:  
  124.   
  125.     // ---構造函數 -------------   
  126.     FileData() : _Row(0), _MinColumn(0), _MaxColumn(0), _FileName(""),  
  127.     _Headstr("") {  
  128.     };  
  129.     // -----------------------------------------------------------------   
  130.     // --讀取文件中的數據   
  131.     void LoadDataFromFile(string FileName);  
  132.     // -----------------------------------------------------------------   
  133.     // --保存數據到文件中   
  134.     void SaveDataToFile(string FileName, string Headstr = "");  
  135.   
  136.     // ------------------------------------------------------------------------   
  137.     unsigned int GetRow() {  
  138.         _Row = _Data.size();  
  139.         return _Row;  
  140.     };  
  141.   
  142.     // ------------------------------------------------------------------------   
  143.     unsigned int GetMinColumn() {  
  144.         _MinColumn = 999999999;  
  145.         for (unsigned int i = 0; i < _Data.size(); i++) {  
  146.             if (_MinColumn > _Data[i].size()) {  
  147.                 _MinColumn = _Data[i].size(); // 獲取最小行   
  148.             }  
  149.         }  
  150.         if (_MinColumn >= 999999999) {  
  151.             _MinColumn = 0;  
  152.         }  
  153.         return _MinColumn;  
  154.     };  
  155.   
  156.     // ------------------------------------------------------------------------   
  157.     unsigned int GetMaxColumn() {  
  158.         _MaxColumn = 0;  
  159.         for (unsigned int i = 0; i < _Data.size(); i++) {  
  160.             if (_MaxColumn < _Data[i].size()) {  
  161.                 _MaxColumn = _Data[i].size(); // 獲取最小行   
  162.             }  
  163.         }  
  164.         return _MaxColumn;  
  165.     };  
  166.   
  167.     // -------------------------------------------------------------------------   
  168.     //////////////////////////////////////////////////////////////////////////   
  169.     // 獲取文件的第一行作為文件頭   
  170.     //////////////////////////////////////////////////////////////////////////   
  171.     string GetHeadstr() {  
  172.         ifstream fin(_FileName.c_str());  
  173.         if (!fin.bad()) {  
  174.             getline(fin, _Headstr);  
  175.         }  
  176.         fin.close();  
  177.         return _Headstr;  
  178.     };  
  179.   
  180.     // ------------------------------------------------------------------------   
  181.     // 提取數據   
  182.     // ------------------------------------------------------------------------   
  183.     void GetData(vector<vector<double> >&Data) {  
  184.         Data.assign(_Data.begin(), _Data.end());  
  185.     };  
  186.   
  187.     // ------------------------------------------------------------------------   
  188.     // 設置數據   
  189.     // ------------------------------------------------------------------------   
  190.     void SetData(vector<vector<double> >&Data) {  
  191.         _Data.assign(Data.begin(), Data.end());  
  192.     };  
  193.     // ------------------------------------------------------------------------   
  194.     void PrintData();  
  195.   
  196.     // -------------默認destructor函數 -------------   
  197.     ~FileData() {  
  198.     };  
  199.     // -----------   
  200. };  
  201.   
  202. // ==============================================================================   
  203. // LoadDataFromFile0   
  204. // ==============================================================================   
  205. void FileData::LoadDataFromFile() {  
  206.   
  207.     _Row = 0;  
  208.     _MinColumn = 999999999;  
  209.     _MaxColumn = 0;  
  210.     if (_Data.size() > 0) {  
  211.         _Data.clear();  
  212.     }  
  213.     ifstream fin(_FileName.c_str());  
  214.     if (!fin.bad()) {  
  215.         string s;  
  216.         while (getline(fin, s)) {  
  217.             vector<double>tempdv;  
  218.             StringToDoubleVector(s, tempdv);  
  219.             if (tempdv.size() > 0) {  
  220.                 _Data.push_back(tempdv);  
  221.                 _Row++;  
  222.                 if (tempdv.size() < _MinColumn) {  
  223.                     _MinColumn = tempdv.size(); // 獲取最小行   
  224.                 }  
  225.                 if (tempdv.size() > _MaxColumn) {  
  226.                     _MaxColumn = tempdv.size(); // 獲取最大行   
  227.                 }  
  228.             }  
  229.   
  230.         }  
  231.     }  
  232.     fin.close();  
  233. }  
  234.   
  235. // ==============================================================================   
  236. // LoadDataFromFile1   
  237. // ==============================================================================   
  238. void FileData::LoadDataFromFile(string FileName) {  
  239.     _FileName = FileName;  
  240.     LoadDataFromFile();  
  241. }  
  242.   
  243. // ==============================================================================   
  244. // SaveDataToFile0   
  245. // ==============================================================================   
  246. void FileData::SaveDataToFile() {  
  247.     if (_Data.size() > 0) {  
  248.         vector<string>strv;  
  249.         for (unsigned int i = 0; i < _Data.size(); i++) {  
  250.             string cstr = "";  
  251.             for (unsigned int j = 0; j < _Data[i].size(); j++) {  
  252.                 char buffer[32];  
  253.                 sprintf(buffer, "%12.6f", _Data[i][j]);  
  254.                 cstr = cstr + " " + buffer;  
  255.             }  
  256.             strv.push_back(cstr);  
  257.         }  
  258.         ofstream ofs(_FileName.c_str());  
  259.         if (!ofs.bad()) {  
  260.             if (_Headstr.length() > 1) {  
  261.                 vector<string>hvs;  
  262.                 SplitString(_Headstr, hvs);  
  263.                 string cstr = "";  
  264.                 for (unsigned int n = 0; n < hvs.size(); n++) {  
  265.                     char buffer[256];  
  266.                     if (hvs[n].size() > 12) {  
  267.                         sprintf(buffer, "%s", hvs[n].c_str());  
  268.                     }  
  269.                     else {  
  270.                         sprintf(buffer, "%12s", hvs[n].c_str());  
  271.                     }  
  272.                     cstr = cstr + " " + buffer;  
  273.                 }  
  274.                 ofs << cstr << endl;  
  275.             }  
  276.             copy(strv.begin(), strv.end(), ostream_iterator<string>(ofs, "\n"));  
  277.         }  
  278.         ofs.close();  
  279.     }  
  280.   
  281. }  
  282.   
  283. // ==============================================================================   
  284. // SaveDataToFile1   
  285. // ==============================================================================   
  286. void FileData::SaveDataToFile(string FileName, string Headstr) {  
  287.     _FileName = FileName;  
  288.     _Headstr = Headstr;  
  289.     SaveDataToFile();  
  290. }  
  291.   
  292. //////////////////////////////////////////////////////////////////////////   
  293. // --用於控制台打印數據的函數PrintData   
  294. //////////////////////////////////////////////////////////////////////////   
  295. void FileData::PrintData() {  
  296.     cout << _FileName.c_str() << endl;  
  297.     if (_Data.size() > 0) {  
  298.   
  299.         string cstr = "";  
  300.         for (unsigned int n = 0; n < _Data[0].size() + 1; n++) {  
  301.             char buffer0[32];  
  302.             char buffer[32];  
  303.             if (n < 1) {  
  304.                 sprintf(buffer, "%12s""Index");  
  305.                 cstr = cstr + buffer+" ";  
  306.             }  
  307.             else {  
  308.                 sprintf(buffer0, "Column%d", n);  
  309.                 sprintf(buffer, "%12s", buffer0);  
  310.                 cstr = cstr + buffer+" ";  
  311.             }  
  312.         }  
  313.         cout << cstr << endl;  
  314.   
  315.         // 輸出數組   
  316.         for (unsigned int i = 0; i < _Data.size(); i++) {  
  317.             char buffer0[32];  
  318.             char buffer[32];  
  319.             sprintf(buffer0, "Row[%d]", i);  
  320.             sprintf(buffer, "%12s", buffer0);  
  321.             cout << buffer << ' ';  
  322.             for (unsigned int j = 0; j < _Data[i].size(); j++) {  
  323.                 sprintf(buffer, " %12.6f", _Data[i][j]);  
  324.                 cout <<buffer;  
  325.             }  
  326.             cout << endl;  
  327.         }  
  328.   
  329.     }  
  330.     else {  
  331.         cout << "There is no data in this file at all!" << endl;  
  332.     }  
  333. }  
  334. // ------------------------------------------------------------------------------   
  335. #endif  
Copyright © Linux教程網 All Rights Reserved