在MFC中打开文件有两种途径:
1.在C***Doc的Serialize里直接添加代码(***表示你工程的名字,比如我的是app_bezier),比如:
void Capp_bezierDoc::Serialize(CArchive& ar) { CDocument::Serialize(ar); ar.Flush(); CString filename = ar.m_strFileName; if (ar.IsStoring()) { // TODO: 在此添加存储代码 } //读 else { read_data(filename); } }
这里read_data函数是真正执行读操作的函数,稍后再表;注意如果想利用添加事件处理器添加打开功能则需要不能写在Doc里,而要写在view里;如果写在Doc中,则会出现无法弹出对话框(如果你自己写对话框也会出错,这是因为对话框应该写在view里),所以第二种途径是:
2.在添加事件处理器时创建在C***view类下,但是这里要自己创建一个对话框,这也不难,注意一下创建对话框的时候打开与另存为的参数是不同的。比如打开一个默认所有文件格式(非Unicode):
CFileDialog dlg(TRUE,NULL,NULL,NULL); if(IDOK!=dlg.DoModal()) { return; } CString filename; filename=dlg.m_ofn.lpstrFile;
filename传回的是打开文件的文件路径,与第一种情况的filename是同样的效果。
逐行读入文件的方式有很多,这里介绍两种。我打开的是txt文件格式,每行三个数据,用空格作为分隔符,回车换行。代码如下:
void Capp_bezierDoc::read_data(CString filename) { vector<double> wR_x , wR_y , w; ifstream in(filename); if(!in) { cerr<<"error:unable to open input file:" <<filename<<endl; return; } string str; in.get(); while(getline(in,str)) { double x,y,ww; if(sscanf(str.c_str(),"%lf %lf %lf",&x,&y,&ww)!=3) { cerr<<"error:false format data!"<<endl; return; } wR_x.push_back(x); wR_y.push_back(y); w.push_back(ww); } }
这里的in.get()用法很有讲究,不同的文件格式用法不一样;因为txt文件里或多或少会有写你看不到的空格。getline则是一行一行读数据。另外一种方法是:
char buf[1024]; vector<float> wR_x , wR_y , w; in.open(filename,ios_base::in); float x,y,ww ; while(in.getline(buf,sizeof(buf))) { sscanf(buf, "%f %f %f", &x , &y ,&ww); wR_x.push_back(x); wR_y.push_back(y); w.push_back(ww); }
PS:我在我的机子上跑通了这些代码,但我不保证也能在你的机子上跑通,所以本文仅供参考。