VC逐行讀寫文件

 

VC逐行讀寫文件(.TXT

用流在寫日誌時,發現如果把"\r\n"直接寫在字符串的尾部,則會造成亂碼,其中的原因網上有很多說明,主要是標準庫與WINDOWS的回車換行的機制略有差別。但只要寫到另一行重起就沒有

用流在寫日誌時,發現如果把"\r\n"直接寫在字符串的尾部,則會造成亂碼,其中的原因網上有很多說明,主要是標準庫與WINDOWS的回車換行的機制略有差別。但只要寫到另一行重起就沒有問題了。

/*****************************************************************************
*                        
寫入日誌文件-C++標準版(UNICODE
*
函 數 名:WriteLogTxt
*
    能 寫入日誌
*
    明:
*
    數:
*
創 建 人:fjf
*
創建時間:2009-09-10
* 修 改 人:
*
修改時間:
*****************************************************************************/

bool CConLog::WriteLogTxt(CString time, CString value)
{
//
定義寫入字符數組
CString tmp = time + value;

//定義輸出流
ofstream oFile;
oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);
    oFile.seekp(0,ios::end);//
回到文件末尾

//寫入文件流
if (oFile.is_open())
{

//下面藍色部分解決了CHAR[]寫入的問題,不用再做拷貝了,增加了安全性
  oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());
   oFile.write(_T("\r\n"), 2);   //
寫在一起會產生亂碼
}
else
{
   oFile.close();
   return false;
}

oFile.close();

return true;
}

/*****************************************************************************
*                        
寫入日誌文件
*
函 數 名:WriteLogTxt
*
    能 寫入日誌
*
    明:
*
    數:
*
創 建 人:fjf
*
創建時間:2009-09-09
* 修 改 人:
*
修改時間:
*****************************************************************************/

bool CConLog::WriteLogTxt(CString key, CString time, CString value)
{
//
讀寫文件全名
if (m_sFullName == _T(""))
{
   AfxMessageBox("
請設置日誌保存路徑!");
   return FALSE;
}

//操作文件
try
{
   this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite);
   m_sfFile.SeekToEnd();
   this->m_sfFile.WriteString(time + _T("\r\n"));
   this->m_sfFile.WriteString(value + _T("\r\n"));
   this->m_sfFile.Close();
}
catch (CFileException &e)
{
   CString error;
   error.Format(_T("%d"),e.m_cause);
   AfxMessageBox(_T("
無法寫入文件!錯誤碼:" + error));
   return false;
}

return true;
}

/*****************************************************************************
*                        
寫入日誌文件-C++標準版(UNICODE
*
函 數 名:WriteLogTxt
*
    能 寫入日誌
*
    明:
*
    數:
*
創 建 人:fjf
*
創建時間:2009-09-10
* 修 改 人:
*
修改時間:
*****************************************************************************/

bool CConLog::WriteLogTxt(CString time, CString value)
{
//
定義寫入字符數組
CString tmp = time + value;

//定義輸出流
ofstream oFile;
oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);
    oFile.seekp(0,ios::end);//
回到文件末尾

//寫入文件流
if (oFile.is_open())
{

//下面藍色部分解決了CHAR[]寫入的問題,不用再做拷貝了,增加了安全性
  oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());
   oFile.write(_T("\r\n"), 2);   //
寫在一起會產生亂碼
}
else
{
   oFile.close();
   return false;
}

oFile.close();

return true;
}

 

查看文章

 

 

VC逐行讀寫日誌文件(TXT

2009-11-03 11:52

最近寫一個日誌讀寫控件的類,發現VCCSdioFileWriteString不能處理中文,雖然把字符集改成多字符形式可以解決這個問題,但這就破壞了程序的兼容性。所以我寫了以下的方法,另外還可以用一咱本地化的方法解決WriteString不能輸入中文方法,附最後(這個也可以使用UNICODE字符集)。

用流在寫日誌時,發現如果把"\r\n"直接寫在字符串的尾部,則會造成亂碼,其中的原因網上有很多說明,主要是標準庫與WINDOWS的回車換行的機制略有差別。但只要寫到另一行重起就沒有問題了。

/*****************************************************************************
*                        
寫入日誌文件
*
函 數 名:WriteLogTxt
*
    能 寫入日誌
*
    明:
*
    數:
*
創 建 人:fjf
*
創建時間:2009-09-09
* 修 改 人:
*
修改時間:
*****************************************************************************/

bool CConLog::WriteLogTxt(CString key, CString time, CString value)
{
//
讀寫文件全名
if (m_sFullName == _T(""))
{
   AfxMessageBox("
請設置日誌保存路徑!");
   return FALSE;
}

//操作文件
try
{
   this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite);
   m_sfFile.SeekToEnd();
   this->m_sfFile.WriteString(time + _T("\r\n"));
   this->m_sfFile.WriteString(value + _T("\r\n"));
   this->m_sfFile.Close();
}
catch (CFileException &e)
{
   CString error;
   error.Format(_T("%d"),e.m_cause);
   AfxMessageBox(_T("
無法寫入文件!錯誤碼:" + error));
   return false;
}

return true;
}

/*****************************************************************************
*                        
寫入日誌文件-C++標準版(UNICODE
*
函 數 名:WriteLogTxt
*
    能 寫入日誌
*
    明:
*
    數:
*
創 建 人:fjf
*
創建時間:2009-09-10
* 修 改 人:
*
修改時間:
*****************************************************************************/

bool CConLog::WriteLogTxt(CString time, CString value)
{
//
定義寫入字符數組
CString tmp = time + value;

//定義輸出流
ofstream oFile;
oFile.open(m_sFullName.GetBuffer(MAX_PATH),ios::app|ios::binary);
    oFile.seekp(0,ios::end);//
回到文件末尾

//寫入文件流
if (oFile.is_open())
{

//下面藍色部分解決了CHAR[]寫入的問題,不用再做拷貝了,增加了安全性
  oFile.write(tmp.GetBuffer(tmp.GetLength()), tmp.GetLength());
   oFile.write(_T("\r\n"), 2);   //
寫在一起會產生亂碼
}
else
{
   oFile.close();
   return false;
}

oFile.close();

return true;
}

/*****************************************************************************
*                        
讀取日誌
*
函 數 名:ReadLogTxt
*
    能 讀取日誌內容
*
    明:
*
    數:key:讀取鍵
*            rlist:
日誌列表控件
*
創 建 人:fjf
*
創建時間:2009-09-09
* 修 改 人:
*
修改時間:
*****************************************************************************/

CString CConLog::ReadLogTxt(CString key,CListCtrl&rlist)
{
//
讀寫文件全名
CString value ;//
返回值
CString myStr = _T("");
CFileException e;

try
{
   //
打開文檔
   if (!this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate| CFile::modeRead ,&e))
   {
    CString error;
    error.Format(_T("%d"),e.m_cause);
    AfxMessageBox(_T("
沒有日誌讀取文件!錯誤碼:" + error));

    return _T("");
   }

   while (this->m_sfFile.ReadString(value))
   {
    //
讀入並保存字符
    myStr = value;
    this->m_sfFile.ReadString(value);
    myStr += value;

    //添加項目
    rlist.InsertItem(0,_T(""),1);
    rlist.SetItemText(0,1,myStr);
   }
   //
關閉文件句柄
   this->m_sfFile.Close();
}
catch (CFileException &e)
{
   CString error;
   error.Format(_T("%d"),e.m_cause);
   AfxMessageBox(_T("
無法讀取文件!錯誤碼:" + error));
   return _T("");
}
return myStr;
}

/*****************************************************************************
*                        
讀取日誌-C++標準版(UNICODE
*
函 數 名:ReadLogTxt
*
    能 讀取日誌內容
*
    明:
*
    數:rlist:日誌列表控件
*
創 建 人:fjf
*
創建時間:2009-09-10
* 修 改 人:
*
修改時間:
*****************************************************************************/

CString CConLog::ReadLogTxt(CListCtrl & rlist)
{
// TODO:
在此添加控件通知處理程序代碼
const int MAX = 80;
char txt[MAX];

ifstream iFile;//標準輸入流
iFile.open(m_sFullName.GetBuffer(MAX),ios::binary);
iFile.seekg (0, ios::beg);//
回到文件頭

//讀取文件
if (iFile.is_open())
{
   CString tmp;
   while(iFile)
   {
    iFile.getline(txt, MAX);
    CString str(txt);   

   }
   //CString str(txt.c_str());
     iFile.close();//
關閉文件流
   return tmp;
}
else
{
   iFile.close();
   return _T("");
}

}

 

 

處理後可以使用WriteString方法,在VS2008測試成功。

#include <locale>//頭文件

void Ctestvc2008Dlg::OnBnClickedButton1()
{
// TODO:
在此添加控件通知處理程序代碼
   CStdioFile m_sfFile;
CString m_sFullName = _T("C:\\Log.txt");
CString time = _T("2009-09-09");
CString value = _T("
這是一個錯誤碼");
try
{
   m_sfFile.Open(m_sFullName,CFile::modeCreate |CFile::modeNoTruncate | CFile::modeWrite);
   m_sfFile.SeekToEnd();
   m_sfFile.WriteString(time + _T(" ") + value);

char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
   setlocale( LC_CTYPE, "chs" );//
設定

   m_sfFile.WriteString(value);//
正常寫入
   setlocale( LC_CTYPE, old_locale );
   free( old_locale );//
還原區域設定

   m_sfFile.Close();
}
catch (CFileException &e)
{
   CString error;
   error.Format(_T("%d"),e.m_cause);
   AfxMessageBox(_T("
無法寫入文件!錯誤碼:" + error));
   return ;
}

return ;
}

void Ctestvc2008Dlg::OnBnClickedButton2()
{
// TODO:
在此添加控件通知處理程序代碼
   //
讀寫文件全名
   const int nBufSize = 512;
        TCHAR chBuf[nBufSize];
        ZeroMemory(chBuf,nBufSize);

        //
獲取當前執行文件的路徑。
        if (GetModuleFileName(NULL,chBuf,nBufSize))
        {
              //
輸出帶文件名稱路徑。
              OutputDebugString(chBuf);
              OutputDebugString(_T("\r\n"));

              //
獲取文件路徑。
              TCHAR* lpStrPath = chBuf;
              PathRemoveFileSpec(lpStrPath);
              OutputDebugString(lpStrPath);
              OutputDebugString(_T("\r\n"));
        }
CStdioFile m_sfFile;
CString value ;//
返回值
CString myStr = _T("");
CString m_sFullName = _T("C:\\Log.txt");
   
try
{
   //
打開文檔
   m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate| CFile::modeRead );
   //char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
   //setlocale( LC_CTYPE, "chs" );//
設定
   while (m_sfFile.ReadString(value))
   {
    //
讀入並保存字符
    myStr = value;
    m_sfFile.ReadString(value);
    myStr += value;

   }
   // setlocale( LC_CTYPE, old_locale );
   //free( old_locale );//
還原區域設定
   //
關閉文件句柄
   m_sfFile.Close();
}
catch (CFileException &e)
{
   CString error;
   error.Format(_T("%d"),e.m_cause);
   AfxMessageBox(_T("
無法讀取文件!錯誤碼:" + error));
   return ;
}
}

*****************************************************************************
*                        
讀取日誌
*
函 數 名:ReadLogTxt
*
    能 讀取日誌內容
*
    明:
*
    數:key:讀取鍵
*            rlist:
日誌列表控件
*
創 建 人:fjf
*
創建時間:2009-09-09
* 修 改 人:
*
修改時間:
*****************************************************************************/

CString CConLog::ReadLogTxt(CString key,CListCtrl&rlist)
{
//
讀寫文件全名
CString value ;//
返回值
CString myStr = _T("");
CFileException e;

try
{
   //
打開文檔
   if (!this->m_sfFile.Open(m_sFullName,CFile::modeCreate | CFile::modeNoTruncate| CFile::modeRead ,&e))
   {
    CString error;
    error.Format(_T("%d"),e.m_cause);
    AfxMessageBox(_T("
沒有日誌讀取文件!錯誤碼:" + error));

    return _T("");
   }

   while (this->m_sfFile.ReadString(value))
   {
    //
讀入並保存字符
    myStr = value;
    this->m_sfFile.ReadString(value);
    myStr += value;

    //添加項目
    rlist.InsertItem(0,_T(""),1);
    rlist.SetItemText(0,1,myStr);
   }
   //
關閉文件句柄
   this->m_sfFile.Close();
}
catch (CFileException &e)
{
   CString error;
   error.Format(_T("%d"),e.m_cause);
   AfxMessageBox(_T("
無法讀取文件!錯誤碼:" + error));
   return _T("");
}
return myStr;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章