1. 程式人生 > >c++中txt檔案的讀取以及在MFC中讀取txt座標資料並完成圖形繪製

c++中txt檔案的讀取以及在MFC中讀取txt座標資料並完成圖形繪製

主要介紹如何讀取txt檔案中的座標資料,並在MFC視窗中繪製出來,工程建立方法和繪圖方法與上一篇博文基本一致,這裡就不再詳贅述,可參考上一篇博文vs2010、MFC視窗中繪製點、線、面

C++中讀取檔案的方法有兩種,一種是來自於C語言的“檔案指標”方法,另一種是C++中的“檔案流”思想。

1、檔案指標

FILE * fopen(const char * path,const char * mode);

-- path: 檔案路徑,如:"F:\test.txt"

-- mode: 檔案開啟方式,例如:

"r" 以只讀方式開啟檔案,該檔案必須存在。

"w" 開啟只寫檔案,若檔案存在則檔案長度清為0,即該檔案內容會消失。若檔案不存在則建立該檔案。

"w+" 開啟可讀寫檔案,若檔案存在則檔案長度清為零,即該檔案內容會消失。若檔案不存

"a" 以附加的方式開啟只寫檔案。若檔案不存在,則會建立該檔案,如果檔案存在,寫入的資料會被加到檔案尾,即檔案原先的內容會被保留。(EOF符保留)

"a+" 以附加方式開啟可讀寫的檔案。若檔案不存在,則會建立該檔案,如果檔案存在,寫入的資料會被加到檔案尾後,即檔案原先的內容會被保留。(原來的EOF符不保留)

"wb" 只寫開啟或新建一個二進位制檔案,只允許寫資料。

"wb+" 讀寫開啟或建立一個二進位制檔案,允許讀和寫。

"ab" 追加開啟一個二進位制檔案,並在檔案末尾寫資料。

"ab+"讀寫開啟一個二進位制檔案,允許讀,或在檔案末追加資料。  

 

    --返回值: 檔案順利開啟後,指向該流的檔案指標就會被返回。如果檔案開啟失敗則返回NULL,並把錯誤程式碼存在errno中。  

示例1:利用檔案指標讀取txt檔案內容

#include <stdio.h>   
#include <stdlib.h>  
int main()
{
   int i = 0;
	float f = 0;
	char str[100] = "";

	FILE* fp = fopen("E:\\test2\\test1.txt", "r");
	if (fp != NULL) {
      
      //根據字元型別讀取txt檔案中的資料
      fscanf(fp, "%d%f%s", &i, &f, str);
      
      //資料讀完之後一定要關閉檔案指標
      fclose(fp);
    }
	//將讀出的內容顯示
	printf(" i = %d\n f = %.2f\n str = %s\n", i, f, str);
}

2、利用檔案流讀取txt檔案中的資料

此方法所涉及到的標頭檔案:#include <fstream>

檔案讀寫的步驟:

1、包含的標頭檔案:#include <fstream>

2、建立流

3、開啟檔案(檔案和流關聯)

4、讀寫 (寫操作:<<,put( ), write( ) 讀操作: >> , get( ),getline( ), read( )),今天只介紹 “ >> ” 讀檔案方法

5、關閉檔案:把緩衝區資料完整地寫入檔案, 新增檔案結束標誌,切斷流物件和外部檔案的連線 (一定要關閉檔案)

#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  
	int datalen=0;

    double num[100];

    //開啟檔案流
    ifstream file("E:\\面向物件課程實習\\面向物件實習課資料\\test2\\test2.txt");
    
    //判斷檔案指標是否為空
    while( ! file.eof() )

    //若不為空,則迴圈讀取存入陣列,這裡的讀取以空格、Tab、回車結束,以單詞為單位
    file>>num[datalen++];

    //輸出陣列元素
    for(int i=0;i<datalen;i++)
    {
        cout<<num[i]<<" ";
    }
	cout<<"\n";

    //關閉檔案流
    file.close();
   
}  

3、在MFC中讀取txt檔案中的座標,並在視窗中繪製圖形

MFC工程建立部分這裡不再贅述,請參考上一篇博文。

3.1、利用檔案指標讀取txt檔案,並畫點

(1)首先建立好MFC介面,新增【畫圖】選單,在【畫圖】選單下新增【畫點】、【畫線】、【畫面】三個子選單。

(2)新增【畫點】選單的事件處理程式

void CMFC_2View::OnDrawPoint()
{
	// TODO: 在此新增命令處理程式程式碼
	//定義一個檔案指標
	FILE *fp;
	//初始化檔案指標,r表示只讀
	fp = fopen("E:/point.txt", "r");

	//定義變數X,Y儲存點的座標值
	int x;
	int y;

	//構造一個DC,傳入當前物件.表示在當前物件使用.
	CClientDC dc(this);
	//畫筆
	CPen pen(PS_SOLID, 3, RGB(25,25,25));
	dc.SelectObject(&pen);
	//畫刷
	CBrush *pBrush = new CBrush(RGB(25,25,25));
	dc.SelectObject(pBrush);
	//判斷檔案指標是否為空
	while (!feof(fp)){
		//若不為空,則往後讀取兩位整數型別,儲存到X,Y中,讀取的同時,檔案指標也會向後移
		fscanf(fp, "%d%d", &x, &y);
		//以(X,Y)為圓心,5為半徑繪製圓點
		dc.Ellipse(x-5,y-5,x+5,y+5);

	}
	//關閉檔案,這一步很重要,C++程式設計中,所有開啟的檔案,最後一定要關閉
	fclose(fp);

}

(3)在point.txt檔案中5個點座標

(4)執行結果如下:

3.2 利用檔案流讀取txt檔案,並完成畫線和畫面

首先需要在前面新增

#include <fstream>  
#include <iostream>

using namespace std;

(1)給【畫線】選單新增事件處理程式

void CMFC_2View::OnDrawLine()
{
	// TODO: 在此新增命令處理程式程式碼
	//定義一個點陣列
	CPoint points[100];
	//定義一個變數來儲存點的個數
	int i=0;
	//定義一個檔案流物件
	ifstream file;
	//初始化這個檔案六物件
	file.open("e://line.txt");

	//判斷檔案流指標是否為空
	while (!file.eof())
	{
		//若不為空迴圈讀取點座標資料
		 file >> points[i].x;
		 file >> points[i].y;
		 i++;
	}
	//關閉檔案流(這一步很重要)
	file.close();
	//構造一個DC,傳入當前物件.表示在當前物件使用.
	CClientDC dc(this);
	//建立一個畫筆.(線的型別, 寬度, 顏色);
	CPen pen(PS_SOLID, 1, RGB(255, 0, 255));
	//把畫筆選到設定描述表當中.覆蓋預設畫筆.
	dc.SelectObject(&pen);
	//polyline方法的兩個引數分別為構成線的點集,以及點的個數
	dc.Polyline(points,i);

}

 

(2)新建一個line.txt檔案,寫入幾個點座標檔案

(3)顯示結果

(4)給【畫面】選單新增事件處理程式

畫線和畫面的檔案讀取方法是一樣,只是最後呼叫的函式不同。

void CMFC_2View::OnDrawPolygon()
{
	// TODO: 在此新增命令處理程式程式碼
	//定義一個點陣列
	CPoint points[100];
	//定義一個變數來儲存點的個數
	int i=0;
	//定義一個檔案流物件
	ifstream file;
	//初始化這個檔案六物件
	file.open("e://polygon.txt");

	//判斷檔案流指標是否為空
	while (!file.eof())
	{
		//若不為空迴圈讀取點座標資料
		file >> points[i].x;
		file >> points[i].y;
		i++;
	}
	//關閉檔案流(這一步很重要)
	file.close();
	//構造一個DC,傳入當前物件.表示在當前物件使用.
	CClientDC dc(this);
	//建立一個畫筆.(線的型別, 寬度, 顏色);
	CPen pen(PS_SOLID, 1, RGB(255, 0, 255));
	//把畫筆選到設定描述表當中.覆蓋預設畫筆.
	dc.SelectObject(&pen);
	//polygon方法的兩個引數分別為構成線的點集,以及點的個數
	dc.Polygon(points,i);
}