歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 在C++ Builder 和GCC(MinGW)中讀寫數據文件的類

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

日期:2017/3/1 10:27:06   编辑:Linux編程

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