分享

VC 逐行读写TXT文件

 心不留意外尘 2016-08-01

   2014

     最近写一个日志读写控件的类,发现VC的CSdioFile的WriteString不能处理中文,虽然把字符集改成多字符形式可以解决这个问题,但这就破坏了程序的兼容性。所以我写了以下的方法,另外还可以用一咱本地化的方法解决WriteString不能输入中文方法,附最后(这个也可以使用UNICODE字符集)。


       用流在写日志时,发现如果把"\r\n"直接写在字符串的尾部,则会造成乱码,其中的原因网上有很多说明,主要是标准库与WINDOWS的回车换行的机制略有差别。但只要写到另一行重起就没有问题了。

  1. *                         写入日志文件-C++标准版(UNICODE)  

  2. * 函 数 名:WriteLogTxt  

  3. * 功    能 写入日志  

  4. * 说    明:  

  5. * 参    数:  

  6. * 创 建 人:fjf  

  7. * 创建时间:2009-09-10  

  8. * 修 改 人:  

  9. * 修改时间:  

  10. *****************************************************************************/  

  11. bool CConLog::WriteLogTxt(CString time, CString value)  

  12. {  

  13. //定义写入字符数组  

  14. CString tmp = time + value;  

  15. //定义输出流  

  16. ofstream oFile;  

  17. oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);  

  18.     oFile.seekp(0,ios::end);//回到文件末尾  

  19. //写入文件流  

  20. if (oFile.is_open())  

  21. {  

  22. //下面蓝色部分解决了CHAR[]写入的问题,不用再做拷贝了,增加了安全性  

  23.   oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());  

  24.    oFile.write(_T("\r\n"), 2);   //写在一起会产生乱码  

  25. }  

  26. else  

  27. {  

  28.    oFile.close();  

  29.    return false;  

  30. }  

  31. oFile.close();  

  32. return true;  

  33. }  

  34. /*****************************************************************************  

  35. *                         写入日志文件  

  36. * 函 数 名:WriteLogTxt  

  37. * 功    能 写入日志  

  38. * 说    明:  

  39. * 参    数:  

  40. * 创 建 人:fjf  

  41. * 创建时间:2009-09-09  

  42. * 修 改 人:  

  43. * 修改时间:  

  44. *****************************************************************************/  

  45. bool CConLog::WriteLogTxt(CString key, CString time, CString value)  

  46. {  

  47. //读写文件全名  

  48. if (m_sFullName == _T(""))  

  49. {  

  50.    AfxMessageBox("请设置日志保存路径!");  

  51.    return FALSE;  

  52. }  

  53. //操作文件  

  54. try  

  55. {  

  56.    this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite);  

  57.    m_sfFile.SeekToEnd();  

  58.    this->m_sfFile.WriteString(time + _T("\r\n"));  

  59.    this->m_sfFile.WriteString(value + _T("\r\n"));  

  60.    this->m_sfFile.Close();  

  61. }  

  62. catch (CFileException &e)  

  63. {  

  64.    CString error;  

  65.    error.Format(_T("%d"),e.m_cause);  

  66.    AfxMessageBox(_T("无法写入文件!错误码:" + error));  

  67.    return false;  

  68. }  

  69. return true;  

  70. }  

  71. /*****************************************************************************  

  72. *                         写入日志文件-C++标准版(UNICODE)  

  73. * 函 数 名:WriteLogTxt  

  74. * 功    能 写入日志  

  75. * 说    明:  

  76. * 参    数:  

  77. * 创 建 人:fjf  

  78. * 创建时间:2009-09-10  

  79. * 修 改 人:  

  80. * 修改时间:  

  81. *****************************************************************************/  

  82. bool CConLog::WriteLogTxt(CString time, CString value)  

  83. {  

  84. //定义写入字符数组  

  85. CString tmp = time + value;  

  86. //定义输出流  

  87. ofstream oFile;  

  88. oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);  

  89.     oFile.seekp(0,ios::end);//回到文件末尾  

  90. //写入文件流  

  91. if (oFile.is_open())  

  92. {  

  93. //下面蓝色部分解决了CHAR[]写入的问题,不用再做拷贝了,增加了安全性  

  94.   oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());  

  95.    oFile.write(_T("\r\n"), 2);   //写在一起会产生乱码  

  96. }  

  97. else  

  98. {  

  99.    oFile.close();  

  100.    return false;  

  101. }  

  102. oFile.close();  

  103. return true;  

  104. }  

  1. 用流在写日志时,发现如果把"\r\n"直接写在字符串的尾部,则会造成乱码,其中的原因网上有很多说明,主要是标准库与WINDOWS的回车换行的机制略有差别。但只要写到另一行重起就没有问题了。  

  2. /*****************************************************************************  

  3. *                         写入日志文件-C++标准版(UNICODE)  

  4. * 函 数 名:WriteLogTxt  

  5. * 功    能 写入日志  

  6. * 说    明:  

  7. * 参    数:  

  8. * 创 建 人:fjf  

  9. * 创建时间:2009-09-10  

  10. * 修 改 人:  

  11. * 修改时间:  

  12. *****************************************************************************/  

  13. bool CConLog::WriteLogTxt(CString time, CString value)  

  14. {  

  15. //定义写入字符数组  

  16. CString tmp = time + value;  

  17. //定义输出流  

  18. ofstream oFile;  

  19. oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);  

  20.     oFile.seekp(0,ios::end);//回到文件末尾  

  21. //写入文件流  

  22. if (oFile.is_open())  

  23. {  

  24. //下面蓝色部分解决了CHAR[]写入的问题,不用再做拷贝了,增加了安全性  

  25.   oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());  

  26.    oFile.write(_T("\r\n"), 2);   //写在一起会产生乱码  

  27. }  

  28. else  

  29. {  

  30.    oFile.close();  

  31.    return false;  

  32. }  

  33. oFile.close();  

  34. return true;  

  35. }  

  36. /*****************************************************************************  

  37. *                         写入日志文件  

  38. * 函 数 名:WriteLogTxt  

  39. * 功    能 写入日志  

  40. * 说    明:  

  41. * 参    数:  

  42. * 创 建 人:fjf  

  43. * 创建时间:2009-09-09  

  44. * 修 改 人:  

  45. * 修改时间:  

  46. *****************************************************************************/  

  47. bool CConLog::WriteLogTxt(CString key, CString time, CString value)  

  48. {  

  49. //读写文件全名  

  50. if (m_sFullName == _T(""))  

  51. {  

  52.    AfxMessageBox("请设置日志保存路径!");  

  53.    return FALSE;  

  54. }  

  55. //操作文件  

  56. try  

  57. {  

  58.    this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite);  

  59.    m_sfFile.SeekToEnd();  

  60.    this->m_sfFile.WriteString(time + _T("\r\n"));  

  61.    this->m_sfFile.WriteString(value + _T("\r\n"));  

  62.    this->m_sfFile.Close();  

  63. }  

  64. catch (CFileException &e)  

  65. {  

  66.    CString error;  

  67.    error.Format(_T("%d"),e.m_cause);  

  68.    AfxMessageBox(_T("无法写入文件!错误码:" + error));  

  69.    return false;  

  70. }  

  71. return true;  

  72. }  

  73. /*****************************************************************************  

  74. *                         写入日志文件-C++标准版(UNICODE)  

  75. * 函 数 名:WriteLogTxt  

  76. * 功    能 写入日志  

  77. * 说    明:  

  78. * 参    数:  

  79. * 创 建 人:fjf  

  80. * 创建时间:2009-09-10  

  81. * 修 改 人:  

  82. * 修改时间:  

  83. *****************************************************************************/  

  84. bool CConLog::WriteLogTxt(CString time, CString value)  

  85. {  

  86. //定义写入字符数组  

  87. CString tmp = time + value;  

  88. //定义输出流  

  89. ofstream oFile;  

  90. oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);  

  91.     oFile.seekp(0,ios::end);//回到文件末尾  

  92. //写入文件流  

  93. if (oFile.is_open())  

  94. {  

  95. //下面蓝色部分解决了CHAR[]写入的问题,不用再做拷贝了,增加了安全性  

  96.   oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());  

  97.    oFile.write(_T("\r\n"), 2);   //写在一起会产生乱码  

  98. }  

  99. else  

  100. {  

  101.    oFile.close();  

  102.    return false;  

  103. }  

  104. oFile.close();  

  105. return true;  

  106. }  

  107.     查看文章           

  108. VC逐行读写日志文件(TXT)  

  109. 2009-11-03 11:52  

  110. 最近写一个日志读写控件的类,发现VC的CSdioFile的WriteString不能处理中文,虽然把字符集改成多字符形式可以解决这个问题,但这就破坏了程序的兼容性。所以我写了以下的方法,另外还可以用一咱本地化的方法解决WriteString不能输入中文方法,附最后(这个也可以使用UNICODE字符集)。  

  111. 用流在写日志时,发现如果把"\r\n"直接写在字符串的尾部,则会造成乱码,其中的原因网上有很多说明,主要是标准库与WINDOWS的回车换行的机制略有差别。但只要写到另一行重起就没有问题了。  

  112. /*****************************************************************************  

  113. *                         写入日志文件  

  114. * 函 数 名:WriteLogTxt  

  115. * 功    能 写入日志  

  116. * 说    明:  

  117. * 参    数:  

  118. * 创 建 人:fjf  

  119. * 创建时间:2009-09-09  

  120. * 修 改 人:  

  121. * 修改时间:  

  122. *****************************************************************************/  

  123. bool CConLog::WriteLogTxt(CString key, CString time, CString value)  

  124. {  

  125. //读写文件全名  

  126. if (m_sFullName == _T(""))  

  127. {  

  128.    AfxMessageBox("请设置日志保存路径!");  

  129.    return FALSE;  

  130. }  

  131. //操作文件  

  132. try  

  133. {  

  134.    this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite);  

  135.    m_sfFile.SeekToEnd();  

  136.    this->m_sfFile.WriteString(time + _T("\r\n"));  

  137.    this->m_sfFile.WriteString(value + _T("\r\n"));  

  138.    this->m_sfFile.Close();  

  139. }  

  140. catch (CFileException &e)  

  141. {  

  142.    CString error;  

  143.    error.Format(_T("%d"),e.m_cause);  

  144.    AfxMessageBox(_T("无法写入文件!错误码:" + error));  

  145.    return false;  

  146. }  

  147. return true;  

  148. }  

  149. /*****************************************************************************  

  150. *                         写入日志文件-C++标准版(UNICODE)  

  151. * 函 数 名:WriteLogTxt  

  152. * 功    能 写入日志  

  153. * 说    明:  

  154. * 参    数:  

  155. * 创 建 人:fjf  

  156. * 创建时间:2009-09-10  

  157. * 修 改 人:  

  158. * 修改时间:  

  159. *****************************************************************************/  

  160. bool CConLog::WriteLogTxt(CString time, CString value)  

  161. {  

  162. //定义写入字符数组  

  163. CString tmp = time + value;  

  164. //定义输出流  

  165. ofstream oFile;  

  166. oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);  

  167.     oFile.seekp(0,ios::end);//回到文件末尾  

  168. //写入文件流  

  169. if (oFile.is_open())  

  170. {  

  171. //下面蓝色部分解决了CHAR[]写入的问题,不用再做拷贝了,增加了安全性  

  172.   oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());  

  173.    oFile.write(_T("\r\n"), 2);   //写在一起会产生乱码  

  174. }  

  175. else  

  176. {  

  177.    oFile.close();  

  178.    return false;  

  179. }  

  180. oFile.close();  

  181. return true;  

  182. }  

  183. /*****************************************************************************  

  184. *                         读取日志  

  185. * 函 数 名:ReadLogTxt  

  186. * 功    能 读取日志内容  

  187. * 说    明:  

  188. * 参    数:key:读取键  

  189. *            rlist:日志列表控件   

  190. * 创 建 人:fjf  

  191. * 创建时间:2009-09-09  

  192. * 修 改 人:  

  193. * 修改时间:  

  194. *****************************************************************************/  

  195. CString CConLog::ReadLogTxt(CString key,CListCtrl&rlist)  

  196. {  

  197. //读写文件全名  

  198. CString value ;//返回值  

  199. CString myStr = _T("");  

  200. CFileException e;  

  201. try  

  202. {  

  203.    //打开文档  

  204.    if (!this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate| CFile::modeRead ,&e))  

  205.    {  

  206.     CString error;  

  207.     error.Format(_T("%d"),e.m_cause);  

  208.     AfxMessageBox(_T("没有日志读取文件!错误码:" + error));  

  209.     return _T("");  

  210.    }  

  211.    while (this->m_sfFile.ReadString(value))  

  212.    {  

  213.     //读入并保存字符  

  214.     myStr = value;  

  215.     this->m_sfFile.ReadString(value);  

  216.     myStr += value;  

  217.     //添加项目  

  218.     rlist.InsertItem(0,_T(""),1);  

  219.     rlist.SetItemText(0,1,myStr);  

  220.    }  

  221.    //关闭文件句柄  

  222.    this->m_sfFile.Close();  

  223. }  

  224. catch (CFileException &e)  

  225. {  

  226.    CString error;  

  227.    error.Format(_T("%d"),e.m_cause);  

  228.    AfxMessageBox(_T("无法读取文件!错误码:" + error));  

  229.    return _T("");  

  230. }  

  231. return myStr;  

  232. }  

  233. /*****************************************************************************  

  234. *                         读取日志-C++标准版(UNICODE)  

  235. * 函 数 名:ReadLogTxt  

  236. * 功    能 读取日志内容  

  237. * 说    明:  

  238. * 参    数:rlist:日志列表控件   

  239. * 创 建 人:fjf  

  240. * 创建时间:2009-09-10  

  241. * 修 改 人:  

  242. * 修改时间:  

  243. *****************************************************************************/  

  244. CString CConLog::ReadLogTxt(CListCtrl & rlist)  

  245. {  

  246. // TODO: 在此添加控件通知处理程序代码  

  247. const int MAX = 80;  

  248. char txt[MAX];  

  249. ifstream iFile;//标准输入流  

  250. iFile.open(m_sFullName.GetBuffer(MAX),ios::binary);  

  251. iFile.seekg (0, ios::beg);//回到文件头  

  252. //读取文件  

  253. if (iFile.is_open())  

  254. {  

  255.    CString tmp;  

  256.    while(iFile)  

  257.    {  

  258.     iFile.getline(txt, MAX);  

  259.     CString str(txt);     

  260.    }  

  261.    //CString str(txt.c_str());  

  262.      iFile.close();//关闭文件流  

  263.    return tmp;  

  264. }  

  265. else  

  266. {  

  267.    iFile.close();  

  268.    return _T("");  

  269. }  

  270. }  

  271. 处理后可以使用WriteString方法,在VS2008测试成功。  

  272. #include <locale>//头文件  

  273. void Ctestvc2008Dlg::OnBnClickedButton1()  

  274. {  

  275. // TODO: 在此添加控件通知处理程序代码  

  276.    CStdioFile m_sfFile;  

  277. CString m_sFullName = _T("C:\\Log.txt");  

  278. CString time = _T("2009-09-09");  

  279. CString value = _T("这是一个错误码");  

  280. try  

  281. {  

  282.    m_sfFile.Open(m_sFullName,CFile::modeCreate |CFile::modeNoTruncate | CFile::modeWrite);  

  283.    m_sfFile.SeekToEnd();  

  284.    m_sfFile.WriteString(time + _T(" ") + value);  

  285. char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );  

  286.    setlocale( LC_CTYPE, "chs" );//设定  

  287.    m_sfFile.WriteString(value);//正常写入  

  288.    setlocale( LC_CTYPE, old_locale );  

  289.    free( old_locale );//还原区域设定  

  290.    m_sfFile.Close();  

  291. }  

  292. catch (CFileException &e)  

  293. {  

  294.    CString error;  

  295.    error.Format(_T("%d"),e.m_cause);  

  296.    AfxMessageBox(_T("无法写入文件!错误码:" + error));  

  297.    return ;  

  298. }  

  299. return ;  

  300. }  

  301. void Ctestvc2008Dlg::OnBnClickedButton2()  

  302. {  

  303. // TODO: 在此添加控件通知处理程序代码  

  304.    //读写文件全名  

  305.    const int nBufSize = 512;  

  306.         TCHAR chBuf[nBufSize];  

  307.         ZeroMemory(chBuf,nBufSize);  

  308.         //获取当前执行文件的路径。  

  309.         if (GetModuleFileName(NULL,chBuf,nBufSize))  

  310.         {  

  311.               //输出带文件名称路径。  

  312.               OutputDebugString(chBuf);  

  313.               OutputDebugString(_T("\r\n"));  

  314.               //获取文件路径。  

  315.               TCHAR* lpStrPath = chBuf;  

  316.               PathRemoveFileSpec(lpStrPath);  

  317.               OutputDebugString(lpStrPath);  

  318.               OutputDebugString(_T("\r\n"));  

  319.         }  

  320. CStdioFile m_sfFile;  

  321. CString value ;//返回值  

  322. CString myStr = _T("");  

  323. CString m_sFullName = _T("C:\\Log.txt");  

  324. try  

  325. {  

  326.    //打开文档  

  327.    m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate| CFile::modeRead );  

  328.    //char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );  

  329.    //setlocale( LC_CTYPE, "chs" );//设定  

  330.    while (m_sfFile.ReadString(value))  

  331.    {  

  332.     //读入并保存字符  

  333.     myStr = value;  

  334.     m_sfFile.ReadString(value);  

  335.     myStr += value;  

  336.    }  

  337.    // setlocale( LC_CTYPE, old_locale );  

  338.    //free( old_locale );//还原区域设定  

  339.    //关闭文件句柄  

  340.    m_sfFile.Close();  

  341. }  

  342. catch (CFileException &e)  

  343. {  

  344.    CString error;  

  345.    error.Format(_T("%d"),e.m_cause);  

  346.    AfxMessageBox(_T("无法读取文件!错误码:" + error));  

  347.    return ;  

  348. }  

  349. }  

  350. *****************************************************************************  

  351. *                         读取日志  

  352. * 函 数 名:ReadLogTxt  

  353. * 功    能 读取日志内容  

  354. * 说    明:  

  355. * 参    数:key:读取键  

  356. *            rlist:日志列表控件   

  357. * 创 建 人:fjf  

  358. * 创建时间:2009-09-09  

  359. * 修 改 人:  

  360. * 修改时间:  

  361. *****************************************************************************/  

  362. CString CConLog::ReadLogTxt(CString key,CListCtrl&rlist)  

  363. {  

  364. //读写文件全名  

  365. CString value ;//返回值  

  366. CString myStr = _T("");  

  367. CFileException e;  

  368. try  

  369. {  

  370.    //打开文档  

  371.    if (!this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate| CFile::modeRead ,&e))  

  372.    {  

  373.     CString error;  

  374.     error.Format(_T("%d"),e.m_cause);  

  375.     AfxMessageBox(_T("没有日志读取文件!错误码:" + error));  

  376.     return _T("");  

  377.    }  

  378.    while (this->m_sfFile.ReadString(value))  

  379.    {  

  380.     //读入并保存字符  

  381.     myStr = value;  

  382.     this->m_sfFile.ReadString(value);  

  383.     myStr += value;  

  384.     //添加项目  

  385.     rlist.InsertItem(0,_T(""),1);  

  386.     rlist.SetItemText(0,1,myStr);  

  387.    }  

  388.    //关闭文件句柄  

  389.    this->m_sfFile.Close();  

  390. }  

  391. catch (CFileException &e)  

  392. {  

  393.    CString error;  

  394.    error.Format(_T("%d"),e.m_cause);  

  395.    AfxMessageBox(_T("无法读取文件!错误码:" + error));  

  396.    return _T("");  

  397. }  

  398. return myStr;  

  399. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多