ini.cpp
上传用户:whyxdz88
上传日期:2007-07-26
资源大小:4k
文件大小:15k
源码类别:

文件操作

开发平台:

Visual C++

  1.  // Ini 相关函数
  2. //------------------------------------------------------------------
  3. // 包含
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <malloc.h>
  7. #include <io.h>
  8. #include <fcntl.h>
  9. #include <assert.h>
  10. #include "ini.h"
  11. //-------------------------------------------------------------------
  12. // 对外接口
  13. //-------------------------------------------------------------------
  14. //-------------------------------------------------------------------------------------
  15. // 初始化/析构释放
  16. //-------------------------------------------------------------------------------------
  17. CIni::CIni()
  18. {
  19. m_lDataLen = 0;
  20. m_strData = NULL;
  21. IndexNum = 0;
  22. IndexList = NULL;
  23. }
  24. CIni::CIni(char *filename)
  25. {
  26. m_lDataLen = 0;
  27. m_strData = NULL;
  28. IndexNum = 0;
  29. IndexList = NULL;
  30. Open(filename);
  31. }
  32. CIni::~CIni()
  33. {
  34. if( m_lDataLen != 0 )
  35. {
  36. SAFE_DELETE( m_strData );
  37. m_lDataLen = 0;
  38. }
  39. if( IndexNum != 0 )
  40. {
  41. SAFE_DELETE( IndexList );
  42. IndexNum = 0;
  43. }
  44. }
  45. //-------------------------------------------------------------------------------------
  46. // 功能:读入配置
  47. // 入口:文件全路径;出口:无
  48. //-------------------------------------------------------------------------------------
  49. bool CIni::Open(char *filename)
  50. {
  51. strcpy(m_strFileName, filename);
  52. SAFE_FREE( m_strData );
  53. int fh;
  54. fh = _open( filename, _O_RDONLY ); // 只读方式
  55. if( fh== -1 )
  56. m_lDataLen = -1;
  57. m_lDataLen = _filelength(fh); // 获取文件长度
  58. _close(fh);
  59. if( m_lDataLen > 0 )// 文件存在
  60. {
  61. m_strData = new char[m_lDataLen];// 申请空间
  62. FILE *fp;
  63. fp=fopen(filename, "rb");
  64. fread(m_strData, m_lDataLen, 1, fp);// 读数据
  65. fclose(fp);
  66. InitIndex(); // 初始化索引
  67. return true;
  68. }
  69. else // 文件不存在
  70. {
  71. m_lDataLen=1;
  72. m_strData = new char[m_lDataLen];
  73. memset(m_strData, 0, 1);
  74. InitIndex();
  75. }
  76. return false;
  77. }
  78. //-------------------------------------------------------------------------------------
  79. // 功能:释放内存
  80. // 入口:无;出口:无
  81. //-------------------------------------------------------------------------------------
  82. void CIni::Close()
  83. {
  84. if( m_lDataLen != 0 )
  85. {
  86. SAFE_DELETE( m_strData );
  87. m_lDataLen = 0;
  88. }
  89. if( IndexNum != 0 )
  90. {
  91. SAFE_DELETE( IndexList );
  92. IndexNum = 0;
  93. }
  94. }
  95. //-------------------------------------------------------------------------------------
  96. // 功能:写入文件
  97. // 入口:文件全路径;出口:无
  98. //-------------------------------------------------------------------------------------
  99. void CIni::Save(char *filename)
  100. {
  101. if( filename==NULL )
  102. filename=m_strFileName;
  103. FILE *fp;
  104. fp=fopen(filename, "wb");
  105. fwrite(m_strData, m_lDataLen, 1, fp);
  106. fclose(fp);
  107. }
  108. //-------------------------------------------------------------------------------------
  109. // 功能:读一字符串数据
  110. // 入口:段名,键名;出口:字符数据
  111. //-------------------------------------------------------------------------------------
  112. char *CIni::ReadText(char *index, char *name)
  113. {
  114. int n=FindIndex(index); // 找索引
  115. int m=FindData(n, name); // 找键名
  116. return ReadText(m); // 获得键值
  117. }
  118. //-------------------------------------------------------------------------------------
  119. // 功能:读一整数
  120. // 入口:段名,键名;出口:整数
  121. //-------------------------------------------------------------------------------------
  122. int CIni::ReadInt(char *index, char *name)
  123. {
  124. int n=FindIndex(index); // 找索引
  125. int m=FindData(n, name); // 找键名
  126. char *str=ReadText(m); // 获得键值
  127. int ret=atoi(str); // 字符转化为整数
  128. free(str);
  129. return ret;
  130. }
  131. //-------------------------------------------------------------------------------------
  132. // 功能:写一字符串数据
  133. // 入口:段名,键名,键值;出口:无
  134. //-------------------------------------------------------------------------------------
  135. void CIni::Write(char *index, char *name, char *string)
  136. {
  137. int n=FindIndex(index);
  138. if( n == -1 ) // index不存在,新建一个索引
  139. {
  140. AddIndex(index); // 添加索引
  141. n=FindIndex(index); // 找到索引位置
  142. n=GotoLastLine(index); // 取得它的下一行
  143. AddData(n, name, string); //在当前位置n加一个数据
  144. return ;
  145. }
  146. int m=FindData(n, name);// index索引存在
  147. if( m==-1 ) // 索引存在,键名不存在,新建数据
  148. {
  149. n=GotoLastLine(index);
  150. AddData(n, name, string); // 在当前位置n加一个数据
  151. return ;
  152. }
  153. // 键名存在
  154. ModityData(n, name, string); // 修改一个数据
  155. return;
  156. }
  157. //-------------------------------------------------------------------------------------
  158. // 功能:写一整数
  159. // 入口:段名,键名,键值;出口:无
  160. //-------------------------------------------------------------------------------------
  161. void CIni::Write(char *index, char *name, int num)
  162. {
  163. char string[32];
  164. sprintf(string, "%d", num);
  165. int n=FindIndex(index);
  166. if( n == -1 ) // 新建索引
  167. {
  168. AddIndex(index); // 添加一个索引
  169. n=FindIndex(index);
  170. n=GotoLastLine(index); //  获得本段最后一行
  171. AddData(n, name, string); // 在当前位置n加一个数据
  172. return;
  173. }
  174. int m=FindData(n, name); // 存在索引,找到键名首位置
  175. if( m==-1 ) // 键名不存在,新建数据
  176. {
  177. n=GotoLastLine(index);
  178. AddData(n, name, string); //在当前位置n加一个数据
  179. return;
  180. }
  181. // 存在数据
  182. ModityData(n, name, string); //修改一个数据
  183. return;
  184. }
  185. //-------------------------------------------------------------------------------------
  186. // 功能:删除一段
  187. // 入口:段名;出口:无
  188. //-------------------------------------------------------------------------------------
  189. void CIni::DeleteIndex(char *index)
  190. {
  191. // char *name;
  192. int n = FindIndex(index); // 找索引
  193. if( n == -1 )
  194. return; // 没有此段返回
  195. n = GotoNextLine(n); // 获得首键名地址
  196. // name = ReadHeadName(n); // 获得=之前的数据
  197. // Write(index, name, 0);
  198. // n = GotoNextLine(n);
  199. int next = GotoLastLine(index); // 获得本段最后一行
  200. if( m_strData[next] == EOF )
  201. {
  202. m_lDataLen = n; // 更新长度
  203. m_strData = (char *)realloc(m_strData, m_lDataLen); // 重新分配内存
  204. InitIndex(); // 更新索引
  205. return;
  206. }
  207. char *temp=new char[m_lDataLen-next];
  208. memcpy(temp, &m_strData[next], m_lDataLen-next); // 把next至最后的这一段长度内容保存
  209. memcpy(&m_strData[n], temp, m_lDataLen-next); // 把next至最后的这一段长度内容向前移
  210. m_lDataLen -= next-n; // 更新长度
  211. m_strData = (char *)realloc(m_strData, m_lDataLen);
  212. // 重新分配内存
  213. InitIndex(); // 更新索引
  214. }
  215. //-------------------------------------------------------------------------------------
  216. // 功能:删除一行
  217. // 入口:段名;出口:无
  218. //-------------------------------------------------------------------------------------
  219. void CIni::DeleteName(char *index,char *name)
  220. {
  221. int m;
  222. int n = FindIndex(index); // 找索引
  223. if( n == -1 )
  224. return; // 没有此段返回
  225. n = FindHead(n, name); // 找键名
  226. if( n == -1 ) // 键名不存在返回
  227. return;
  228. m = GotoNextLine(n); // 获得下一行的起始位置
  229. char *temp=new char[m_lDataLen-m];
  230. memcpy(temp, &m_strData[m], m_lDataLen-m); // 把m至最后的这一段长度内容保存
  231. memcpy(&m_strData[n], temp, m_lDataLen-m); // 把m至最后的这一段长度内容向前移
  232. m_lDataLen -= m-n; // 更新长度
  233. m_strData = (char *)realloc(m_strData, m_lDataLen); // 重新分配内存
  234. InitIndex(); // 更新索引
  235. }
  236. //--------------------------------------------------------------------------
  237. // 内部函数
  238. //--------------------------------------------------------------------------
  239. //-------------------------------------------------------------------------------------
  240. // 功能:计算出所有的索引位置
  241. // 入口:无;出口:无
  242. //-------------------------------------------------------------------------------------
  243. void CIni::InitIndex() 
  244. {
  245. IndexNum=0;
  246. for(int i=0; i<m_lDataLen; i++)
  247. {
  248. if( m_strData[i]=='[' && ( m_strData[i-1]=='n' || i==0 ) )// 找到一个
  249. IndexNum++;
  250. }
  251. SAFE_DELETE( IndexList );
  252. if( IndexNum>0 )
  253. IndexList=new int[IndexNum];// 申请内存
  254. int n=0;
  255. for(i=0; i<m_lDataLen; i++)
  256. {
  257. if( m_strData[i]=='[' && ( m_strData[i-1]=='n' || i==0 ) )
  258. {
  259. IndexList[n]=i+1; // 记录位置
  260. n++;
  261. }
  262. }
  263. }
  264. //-------------------------------------------------------------------------------------
  265. // 功能:返回指定段名位置
  266. // 入口:指定段名;出口:首位置
  267. //-------------------------------------------------------------------------------------
  268. int CIni::FindIndex(char *string)
  269. {
  270. for(int i=0; i<IndexNum; i++)
  271. {
  272. char *str=ReadText( IndexList[i] );
  273. if( strcmp(string, str) == 0 )
  274. {
  275. SAFE_FREE( str );
  276. return IndexList[i];
  277. }
  278. SAFE_FREE( str );
  279. }
  280. return -1;
  281. }
  282. //-------------------------------------------------------------------------------------
  283. // 功能:返回指定数据的位置
  284. // 入口:索引,指定键名;出口:键名首位置
  285. //-------------------------------------------------------------------------------------
  286. int CIni::FindHead(int index, char *string)
  287. {
  288. int p=index; // 指针
  289. char *name;
  290. while(1)
  291. {
  292. p = GotoNextLine(p); // 获得下一行起始位置
  293. name = ReadHeadName(p); // 获得=之前的数据
  294. if( strcmp(string, name)==0 )
  295. {
  296. SAFE_FREE( name );
  297. return p;
  298. }
  299. SAFE_FREE( name );
  300. if( p>=m_lDataLen || m_strData[p] == '[' ) return -1;
  301. }
  302. return -1;
  303. }
  304. //-------------------------------------------------------------------------------------
  305. // 功能:返回指定数据的位置
  306. // 入口:索引,指定键名;出口:键名=号的位置
  307. //-------------------------------------------------------------------------------------
  308. int CIni::FindData(int index, char *string)
  309. {
  310. int p=index; // 指针
  311. char *name;
  312. while(1)
  313. {
  314. p = GotoNextLine(p); // 获得下一行起始位置
  315. if( p>=m_lDataLen || m_strData[p] == '[' ) return -1;
  316. name = ReadDataName(p); // 获得=之前的数据
  317. if( strcmp(string, name)==0 )
  318. {
  319. SAFE_FREE( name );
  320. return p;
  321. }
  322. SAFE_FREE( name );
  323. }
  324. return -1;
  325. }
  326. //-------------------------------------------------------------------------------------
  327. // 功能:获得下一行起始位置
  328. // 入口:位置;出口:下一行首位置
  329. //-------------------------------------------------------------------------------------
  330. int CIni::GotoNextLine(int p)
  331. {
  332. for(int i=p; i<m_lDataLen; i++)
  333. {
  334. if( m_strData[i]=='n' )
  335. return i+1;
  336. }
  337. return i;
  338. }
  339. //-------------------------------------------------------------------------------------
  340. // 功能:在指定位置读一数据名称
  341. // 入口:行首位置;出口:=号后的字符串
  342. //-------------------------------------------------------------------------------------
  343. char *CIni::ReadDataName(int &p)
  344. {
  345. char chr;
  346. char *Ret;
  347. int m=0;
  348. Ret=new char[MAX_PATH];
  349. memset(Ret, 0, MAX_PATH);
  350. for(int i=p; i<m_lDataLen; i++)
  351. {
  352. chr = m_strData[i];
  353. if( chr == 'r' || chr == '=' || chr == ';' )// 结束
  354. {
  355. p=i+1;
  356. return Ret;
  357. }
  358. Ret[m]=chr;
  359. m++;
  360. }
  361. return Ret;
  362. }
  363. //-------------------------------------------------------------------------------------
  364. // 功能:在指定位置读一数据名称
  365. // 入口:行首位置;出口:=号后的字符串
  366. //-------------------------------------------------------------------------------------
  367. char *CIni::ReadHeadName(int &p)
  368. {
  369. char chr;
  370. char *Ret;
  371. int m=0;
  372. Ret=new char[MAX_PATH];
  373. memset(Ret, 0, MAX_PATH);
  374. for(int i=p; i<m_lDataLen; i++)
  375. {
  376. chr = m_strData[i];
  377. if( chr == 'r' || chr == '=' || chr == ';' )// 结束
  378. {
  379. return Ret;
  380. }
  381. Ret[m]=chr;
  382. m++;
  383. }
  384. return Ret;
  385. }
  386. //-------------------------------------------------------------------------------------
  387. // 功能:在指定位置读一字符串,p为索引位置
  388. // 入口:行首位置;出口:=号前的字符串
  389. //-------------------------------------------------------------------------------------
  390. char *CIni::ReadText(int p)
  391. {
  392. char chr;
  393. char *Ret;
  394. int n=p, m=0;
  395. int LineNum = GotoNextLine(p) - p + 1;
  396. Ret=new char[LineNum];
  397. memset(Ret, 0, LineNum);
  398. for(int i=0; i<m_lDataLen-p; i++)
  399. {
  400. chr = m_strData[n];
  401. if( chr == ';' || chr == 'r' || chr == 't' || chr == ']' )// 结束
  402. {
  403. return Ret;
  404. }
  405. Ret[m]=chr;
  406. m++;
  407. n++;
  408. }
  409. return Ret;
  410. }
  411. //-------------------------------------------------------------------------------------
  412. // 功能:加入一个索引
  413. // 入口:索引;出口:无
  414. //-------------------------------------------------------------------------------------
  415. void CIni::AddIndex(char *index) 
  416. {
  417. char str[MAX_PATH];
  418. memset(str, 0, MAX_PATH);
  419. sprintf(str,"rn[%s]rn",index);
  420. m_strData = (char *)realloc(m_strData, m_lDataLen+strlen(str)); // 重新分配内存
  421. sprintf(&m_strData[m_lDataLen], "%s", str); // 写入索引
  422. m_lDataLen+=strlen(str); // 长度指向最后
  423. InitIndex(); // 重建索引
  424. }
  425. //-------------------------------------------------------------------------------------
  426. // 功能:在当前位置加入一个数据
  427. // 入口:当前行的首点,键名,键值;出口:无
  428. //-------------------------------------------------------------------------------------
  429. void CIni::AddData(int p, char *name, char *string)
  430. {
  431. char *str;
  432. int len;
  433. str=new char[2*MAX_PATH];
  434. memset(str, 0, 2*MAX_PATH);
  435. sprintf(str,"%s=%srn",name,string);
  436. len=strlen(str);
  437. m_strData = (char *)realloc(m_strData, m_lDataLen+len); // 重新分配内存
  438. char *temp=new char[m_lDataLen-p];
  439. memcpy(temp, &m_strData[p], m_lDataLen-p); // 把p至最后的这一段长度内容保存
  440. memcpy(&m_strData[p+len], temp, m_lDataLen-p); // 把p至最后的这一段长度内容向后移
  441. memcpy(&m_strData[p], str, len); // 在p存入字符串
  442. m_lDataLen+=len; // 长度增加
  443. SAFE_DELETE(temp);
  444. SAFE_DELETE(str);
  445. InitIndex(); // 更新索引
  446. }
  447. //-------------------------------------------------------------------------------------
  448. // 功能:在当前位置修改一个数据的值
  449. // 入口:当前行的首点,键名,键值;出口:无
  450. //-------------------------------------------------------------------------------------
  451. void CIni::ModityData(int p, char *name, char *string)
  452. {
  453. int n=FindData(p, name);
  454. char *t=ReadText(n);
  455. p=n+strlen(t); // p指向本行最后,n指向=号后 
  456. if( strlen(t)>0 ) free(t);
  457. int newlen=strlen(string);
  458. int oldlen=p-n;
  459. m_strData = (char *)realloc(m_strData, m_lDataLen+newlen-oldlen); // 重新分配内存
  460. char *temp=new char[m_lDataLen-p];
  461. memcpy(temp, &m_strData[p], m_lDataLen-p); // 把p至最后的这一段长度内容保存
  462. memcpy(&m_strData[n+newlen], temp, m_lDataLen-p); // 把p至最后的这一段长度内容向后移
  463. memcpy(&m_strData[n], string, newlen); // 在n存入新字符串
  464. m_lDataLen+=newlen-oldlen; // 更新长度
  465. SAFE_DELETE( temp );
  466. InitIndex(); // 更新索引
  467. }
  468. //-------------------------------------------------------------------------------------
  469. // 功能:把指针移动到本INDEX的最后一行
  470. // 入口:索引点;出口:段内最后一行首位置
  471. //-------------------------------------------------------------------------------------
  472. int CIni::GotoLastLine(char *index)
  473. {
  474. int n=FindIndex(index);
  475. n=GotoNextLine(n);
  476. while(1)
  477. {
  478. if( m_strData[n] == 'r' || m_strData[n] == EOF || m_strData[n] == -3 || m_strData[n] == ' ' || m_strData[n] == '/' || m_strData[n] == 't' || m_strData[n] == 'n' )
  479. {
  480. return n;
  481. }
  482. else
  483. {
  484. n=GotoNextLine(n);
  485. if( n >= m_lDataLen ) return n;
  486. }
  487. }
  488. }