在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.bkjia.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  
  • 1
  • 2
  • 下一页

相关内容