1. 程式人生 > >MFC之TXT文字檔案的讀寫

MFC之TXT文字檔案的讀寫

正確的文字檔案讀寫過程:

1、定義檔案變數;2、開啟指定的檔案;3、向文字檔案中寫入資訊;4、從文字檔案中讀取資訊;5、關閉檔案

 

1、定義檔案變數(CStdioFile類是CFile類的擴充套件)

定義檔案變數格式:CStdioFile 檔案變數(操作檔案時模式是text模式)。CFile(操作檔案預設的是Binary模式)

2、開啟指定檔案

可以直接通過CStdioFile的建構函式來開啟磁碟檔案,同時可以用標誌位指定開啟方式(只讀、只寫、

讀寫等):

CStdioFile(LPCTSTR lpszFileName,UINT nOpenFlags);

其中,lpszFileName表示要開啟的檔名,可以是相對路徑或絕對路徑

nOpenFlags設定檔案開啟方式標誌位,可以指定用“|”連線多個標誌位。下面是常用的開啟標誌:

CFile::typeText:以文字檔案的形式開啟檔案

CFile::typeBinary:以二進位制檔案的形式開啟檔案

CFile::modeCreate:如果指定檔名不存在,則新建檔案;如果檔案存在並且沒有設定CFile::modeNoTruncate標誌,則清空檔案

CFile::modeNoTruncate:如果檔案存在,不把它的長度刪除為0(即不清空檔案中的資料)。

CFile::modeRead:以只讀方式開啟檔案

CFile::modeReadWrite:以可讀可寫方式開啟檔案

CFile::modeWrite:以只寫方式開啟檔案

CFile::shareDenyNone:檔案開啟後,不禁止其他程序對檔案的讀寫操作

CFile::shareExclusive:檔案開啟後,禁止其他程序對檔案的讀寫操作

CFile::shareDenyRead:檔案開啟後,禁止其他程序對檔案的讀操作

CFile::shareDenyWrite:檔案開啟後,禁止其他程序對檔案的寫操作

此外,可以不在建構函式中開啟檔案,通過呼叫空的建構函式CStdioFile(),然後用CStdioFile::Open()開啟檔案。

Open函式的前兩個引數和非空建構函式的引數相同,其宣告如下:

BOOL Open(LPCTSTR lpszFileName,UINT nOpenFlags,CFileException* pError=NULL);

第3個引數與開啟失敗時的異常處理有關。

例項1 :以只讀方式開啟一個檔案

步驟:

char * pszFileName = "C:\\myfile.txt";

CStdioFile myFile;

CFileException fileException;

if(!myFile.Open(pszFileName,CFile::modeCreate|CFile::typeText|CFile::modeRead),&fileException)

{

TRACE("Can't open file %s, error = %u\n",pszFileName,fileException.m_cause);

}

執行結果:如果C:\下沒有myfile.txt檔案,則新生成該檔案。

3、向文字檔案中寫入資訊

CStdioFile提供了函式WriteString來向文字檔案中寫入文字,WriteString函式的格式如下:

void WriteString(LPCTSTR,lpsz);

WriteString的引數lpsz是一個以"\0"字元結束的字串,要把這個字串的內容寫入檔案。

提示:使用WriteString函式時,如果希望每執行一次WriteString,文字檔案中的內容就會自動換行一次

那麼就需要在需要換行的地方輸出"\n";

myFile.WriteString("第1行\n");

例項2:向檔案中寫入文字

char* pszFileName="C:\\myfile.txt";

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(pszFileName,CFile::typeText|CFile::modeCreate|CFile::modeReadWrite),&fileException)

{

myFile.WriteString("第1行\n");

CString strOrder;

strOrder.Format("%d,%.3f",66,88.88);

myFile.WriteString(strOrder);

}

else

{

TRACE("Can't open file %s,error=%u\n",pszFileName,fileException.m_cause);

}

程式執行結果:C:\myfile.txt檔案中內容如下:

第1行

66,88.880

4、從文字檔案中讀取資訊

CStidoFile提供了函式ReadString來讀取文字,ReadString有兩種形式,一種為:

virtual LPTSTR ReadString(LPTSTR lpsz, UINIT nMax);

ReadString函式的引數如下:

lpsz :是使用者提供的一個指向字串的指標,它用來接受從檔案讀出的文字,以”\0”結束。

nMax是本次所允許讀入的文字字元個數,不計“\0”字元,也就是說最多能讀入nMax-1個文字字元。

ReadString的返回值是一個LPTSTR型別的指標,它指向從檔案讀出的文字字串,如果到達檔案尾,則返回NULL。

ReadString的另一種形式為:

BOOL ReadString(CString& rString);

引數rString用來容納從檔案讀出的文字。

CString版本忽略回車換行符,返回值是一個布林值。如果返回值為FALSE,表示因到達檔案尾而沒有讀到任何字元。

提示:每執行一次ReadString,就會自動從文字檔案中讀取一行資料,同時檔案操作指標會自動跳轉到下一行。

例項3:從檔案中讀取文字資訊

char* pszFileName="C:\\myfile.txt";

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(pszFileName,CFile::typeText|CFile::modeReadWrite),&fileException)

{

myFile.SeekToBegin();

CString str1;

myFile.ReadString(str1);

CString str2;

myFile.ReadString(str2);

AfxMessageBox(str1+str2);

}

else

{

TRACE("Can't open file %s,error=%u\n",pszFileName,fileException.m_cause);

}

myFile.Close();

5.關閉檔案

對檔案的操作完成後,使用CloseFile關閉檔案。

函式CStdioFile::Close關閉一個檔案,一般一個檔案使用完畢就應該關閉它:

myFile.Close();

錯誤的文字檔案讀寫過程

在讀寫文字檔案的時候,最常見的錯誤是---操作檔案不存在。這種錯誤產生的典型原因有:

1.路徑錯誤

char * pszFileName="C:\\Windows\\MyFile.txt";

CStdioFile myFile;

CFileException fileException;

if(!myFile.Open(pszFileName,CFile::modeCreate|CFile::typeText|CFile::modeReadWrite),&fileException)

{

//檔案操作程式碼

}

else

{

TRACE("Can't open file %s, error = %u\n",pszFileName,fileException.m_cause);

}

myFile.Close();

由於將檔案變數與一個絕對路徑的檔名關聯,而程式的資料通常儲存在相對路徑下,所以一旦相對路徑和相對路徑不一致時,就會出錯。

舉例而言,上一段程式本意是想從windows的安裝目錄下面的MyTextFile.txt檔案中讀取一行資料,但是如果作業系統安裝的路徑不是C:\Windwos,而是C:\Winnt,那麼這段程式就會出錯。

解決方法是在程式中使用相對路徑,改正後的程式如下:

//獲取windows路徑

LPTSTR lpBuffer=new char[MAX_PATH];

::GetWindowsDirectory(lpBuffer,MAX_PATH);

strcat(lpBuffer,"\\MyFile.txt");

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(lpBuffer,CFile::typeText|CFile::modeCreate|CFile::modeReadWrite),&fileException)

{

//檔案操作程式碼

}

else

{

TRACE("Can't open file %s, error = %u\n",pszFileName,fileException.m_cause);

}

myFile.Close();

由於將檔案變數與一個絕對路徑的檔名關聯,而程式的資料通常儲存在相對路徑下,所以一旦相對路徑和相對路徑不一致時,就會出錯。

舉例而言,上一段程式本意是想從windows的安裝目錄下面的MyTextFile.txt檔案中讀取一行資料,但是如果作業系統安裝的路徑不是C:\Windwos,而是C:\Winnt,那麼這段程式就會出錯。

解決方法是在程式中使用相對路徑,改正後的程式如下:

//獲取windows路徑

LPTSTR lpBuffer=new char[MAX_PATH];

::GetWindowsDirectory(lpBuffer,MAX_PATH);

strcat(lpBuffer,"\\MyFile.txt");

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(lpBuffer,CFile::typeText|CFile::modeCreate|CFile::modeReadWrite),&fileException)

{

//檔案操作程式碼

}

else

{

TRACE("Can't open file %s, error = %u\n",pszFileName,fileException.m_cause);

}

CString strFileTitle="MyFile.txt";

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(strFileTitle,CFile::typeText|CFile::modeReadWrite),&fileException)

{

//檔案操作程式碼

myFile.WriteString("測試!");

}

else

{

TRACE("Can't open file %s, error = %u\n",pszFileName,fileException.m_cause);

}

myFile.Close();

2.操作檔案不存在

如果應用程式所有路徑下面不存在MyFile.txt檔案,那麼在WriteString寫入資訊時就會出錯。

解決辦法就是在程式中開啟檔案前要檢查是否存在此檔案。如下程式:

CString strFileTitle="MyFile.txt";

CFileFind finder;

if(finder.FindFile(strFileTitle))

{

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(lpBuffer,CFile::typeText|CFile::modeCreate|CFile::modeReadWrite),&fileException)

{

//檔案操作程式碼

}

else

{

TRACE("Can't open file %s, error = %u\n",pszFileName,fileException.m_cause);

}

}

else

{

TRACE("Can't find file %s\n",strFileTitle);

}

myFile.Close();

3.超越檔案許可權進行讀寫操作

在開啟檔案的過程中,通過引數指定了檔案的讀寫許可權,如果讀寫的操作沒有和相應的許可權對應,就會出現錯誤。

下面的程式就是典型的忽略了檔案操作許可權的例子:

CString strFileTitle="MyFile.txt";

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(strFileTitle,CFile::typeText|CFile::modeCreate|CFile::NoTruncate|CFile::modeRead),&fileException)

{

//檔案操作程式碼

myFile.WriteString("測試!");

}

else

{

TRACE("Can't open file %s,error=%u\n",strFileTitle,fileException.m_cause);

}

myFile.Close();

支招兒:

1.準確定位檔案的路徑

操作檔案的過程中,經常需要將文字檔案放在程式自身的目錄中,但是如果僅僅在程式中使用不指定任何路徑資訊的相對路徑,如:

myFile.Open("MyFile.txt",CFile::modeCreate|CFile::typeText|CFile::modeReadWrite);

那麼就有可能出現不能正確定位的情況,準確定位檔案位置的方法是獲得可執行程式自身的絕對路徑,如:

TCHAR FilePath[MAX_PATH];

GetModuleFileName(NULL,FilePath,MAX_PATH);

(_tcstchr(FilePath,'\\'))[1]=0;

lstrcat(FilePath,_T("MyFile.txt"));

CStdioFile myFile;

CFileException fileException;

if(myFile.Open(FilePath,CFile::modeCreate|CFile::typeText|CFile::modeReadWrite),&fileException)

{

//檔案操作程式碼

}

else

{

TRACE("Can't open file %s,error=%u\n",FilePath,fileException.m_cause);

}

myFile.Close();

2.讀文字檔案指定的一行,並得到文字檔案的總行數。

讀文字檔案指定的一行,並得到文字檔案的總行數

要統計文字檔案的總行數,可以從頭逐行讀,直到檔案尾,程式:

CStdioFile myFile;

CFileException fileException;

if(myFile.Open("MyFile.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::typeText|CFile::modeReadWrite),&fileException)

{

CString strContent;

int order=1;

while(myFile.ReadString(strContent))

{

if(2==order)

{

AfxMessageBox(strContent);

}

order=order+1;

}

}

else

{

TRACE("Can't open file");

}

myFile.Close();