(工具:VS2010)
• 掌握文件对话框的使用方法
• 掌握C++文件操作的一般步骤及实现方法
• 了解MFC文件操作的特 点及使用方法
要求:编制简单的Cass数据文件进行数据整理的程序。整理后的数据文件中要求无重复点数据,且数据按点号大小的升序进行排序。要求整理后的数据按与原始数据文件同样的格式保存为另外一个文件。
示例数据“民用园燃气dat”文件数据格式:
总点数
点号,编码,X,Y,H
…
3.3.1文件:<Data.h>
/***************************************************************************
* 文件名: *
* *
* 描述:储存每行数据 *
* *
* 历史:**日期** **理由** **签名** *
* 2019年4月19日 创建 张 *
* *
* 外部过程: *
* *
/**************************************************************************/
class CData
{
public:
CData(void);
~CData(void);
int iID;
CString strCode;
double dX;
double dY;
double dH;
int iSum;//仅在第一个元素中使用
};
3.3.2文件:<Data.cpp>
#include "StdAfx.h"
#include "Data.h"
CData::CData(void)
{
}
CData::~CData(void)
{
}
3.3.3文件:<CSupport.h>
/***************************************************************************
* 文件名: *
* *
* 描述:封装所有函数的类 *
* *
* 历史:**日期** **理由** **签名** *
* 2019年4月19日 创建 张 *
* *
* 外部过程: *
* *
/**************************************************************************/
#pragma once
#include <locale.h>
#include "Data.h"
class CSupport
{
public:
CData *a;
CSupport(void);
~CSupport(void);
CString * SplitString(CString str, char split, int& iSubStrs);
CData * read(CString &strView);
void Out(CData *a,CString &strOut);
};
3.3.4文件:<CSupport.cpp>
#include "StdAfx.h"
#include "Support.h"
CSupport::CSupport(void)
{
if(a!=NULL){
delete[] a;}
}
CSupport::~CSupport(void)
{
}
/***************************************************************************
* 名字:CString * CSupport::SplitString(CString str, char split, int& iSubStrs)*
* *
* 描述:字符串分割函数2 *
* *
* 历史:**日期** **理由** **签名** *
* 2019年4月19日 创建该函数 张 *
* 参数: 1.CString str *
* 2.char split *
* 3.int& iSubStrs *
* 返回值:返回指针 指针带有动态数组的内容 *
* *
* 注: *
/**************************************************************************/
CString * CSupport::SplitString(CString str, char split, int& iSubStrs)
{
int iPos = 0; //分割符位置
int iNums = 0; //分割符的总数
CString strTemp = str;
CString strRight;
//先计算子字符串的数量
while (iPos != -1)
{
iPos = strTemp.Find(split);
if (iPos == -1)
{
break;
}
strRight = strTemp.Mid(iPos + 1, str.GetLength());
strTemp = strRight;
iNums++;
}
if (iNums == 0) //没有找到分割符
{
//子字符串数就是字符串本身
iSubStrs = 1;
return NULL;
}
//子字符串数组
iSubStrs = iNums + 1; //子串的数量 = 分割符数量 + 1
CString* pStrSplit;
pStrSplit = new CString[iSubStrs];
strTemp = str;
CString strLeft;
for (int i = 0; i < iNums; i++)
{
iPos = strTemp.Find(split);
//左子串
strLeft = strTemp.Left(iPos);
//右子串
strRight = strTemp.Mid(iPos + 1, strTemp.GetLength());
strTemp = strRight;
pStrSplit[i] = strLeft;
}
pStrSplit[iNums] = strTemp;
return pStrSplit;
}
/***************************************************************************
* 名字:CData * CSupport::read(CString &strView) *
* *
* 描述:读取函数 *
* *
* 历史:**日期** **理由** **签名** *
* 2019年4月19日 创建该函数 张 *
* 参数: 1.CString &strView *
* 返回值:返回开辟动态数组的首地址 另外将提取的值赋给strView *
* *
* 注: *
/**************************************************************************/
CData * CSupport::read(CString &strView)
{
CFileDialog dlgFile(TRUE,_T("txt"),NULL,
OFN_ALLOWMULTISELECT|OFN_EXPLORER,
//_T("(文本文件)|*.txt"));
_T(""));
if(dlgFile.DoModal()==IDCANCEL) return NULL;
CString strName=dlgFile.GetPathName();//获取打开文件文件名(路径)
setlocale(LC_ALL,"");
CStdioFile sf;
if(! sf.Open(strName,CFile::modeRead)) return NULL;
CString strLine;
CString strContent;//接受内容字符串
strContent.Empty();
BOOL bEOF =sf.ReadString (strLine);
if(!bEOF)
{
AfxMessageBox(_T("数据有误,请检查数据文件!"));
return NULL;
}
int iPointCount;
iPointCount=_ttoi(strLine);//读取点数
a=new CData [iPointCount];//创建动态数组
a[0].iSum=iPointCount;
int i=0 ;
int n=0;//为下文读取做铺垫
while (bEOF)
{
//strContent+=strLine;
bEOF=sf.ReadString(strLine);
CString *pstrData =SplitString(strLine,',',n);
if(pstrData==NULL) continue;
a[i].iID =_ttoi(pstrData[0]);
a[i].strCode =pstrData[1];
a[i].dX =_tstof(pstrData[2]);
a[i].dY =_tstof(pstrData[3]);
a[i].dH =_tstof(pstrData[4]);
i++;
delete [] pstrData;
pstrData=NULL;
}
sf.Close();
CString Result;
for(int i=0;i<iPointCount;i++)
{
Result.Format(_T("%d,%s,%.4f,%.4f,%.4f\r\n"),a[i].iID,a[i].strCode,a[i].dX,a[i].dY,a[i].dH);
strView+=Result;
}
return a;
}
/***************************************************************************
* 名字:void CSupport::Out(CData *a,CString &strOut) *
* *
* 描述:输出函数,借助动态数组a,输出结果至txt文件,另外赋值至strOut *
* *
* 历史:**日期** **理由** **签名** *
* 2019年4月19日 创建该函数 张 *
* 参数: 1.CData *a *
* 2.CString &strOut *
* 返回值:返回开辟动态数组的首地址 另外将提取的值赋给strView *
* *
* 注: *
/**************************************************************************/
void CSupport::Out(CData *a,CString &strOut)
{
const int length=a[0].iSum;
CData test;
for(int i=0;i<length;i++)
{
for(int j=0;j<length-i-1;j++)//此处很重要
{
if(a[j].iID<a[j+1].iID)//根据单一数据项,对整个结构体进行排序
{
test=a[j+1];//结构体允许整体赋值
a[j+1]=a[j];
a[j]=test;
}
}
}
int i=0;
int j=0;
while (i < length)
{
if (a[i].iID == a[++j].iID)
{
// 遇到重复元素,将其值置为-1
a[j].iID = -1; // -1是标记值,可以换成其他值,但不能和要排序的数字冲突
} else {
i = j;
}
}
int t=0;
CString Result1;
//for(int i=0;i
for(int i=length-1;i>=0;i--)//降序排序
{
if (a[i].iID != -1){
++t;
Result1.Format(_T("%d,%s,%.4f,%.4f,%.4f\r\n"),a[i].iID,a[i].strCode,a[i].dX,a[i].dY,a[i].dH);
strOut+=Result1;}
}
CStdioFile SF;
CString strLine;
setlocale(LC_ALL,"");
if(!SF.Open(_T("Result.txt"), CFile::modeCreate|CFile::modeWrite)) return;
strLine.Format(_T("%s%d%s\r\n"),
_T("-------------------转换后的坐标(点数:"),
t,
_T(")-----------------------")
);
SF.WriteString(strLine);
SF.WriteString(strOut);
SF.Close();
AfxMessageBox(_T("成功!已输入至“Result.txt”中"));
}
3.3.5文件:<RS_110_zhang_SY5Dlg.cpp> (只摘取部分)
/***************************************************************************
* 文件名: *
* *
* 描述:Dialog 按钮函数 *
* *
* 历史:**日期** **理由** **签名** *
* 2019年4月19日 创建 张 *
* *
* 外部过程: *
* *
/**************************************************************************/
CSupport k;//全局
void CRS_110_zhang_SY5Dlg::OnBnClickedButton2Read1()
{
// TODO: 在此添加控件通知处理程序代码
//if(dlgFile.DoModal()==IDCANCEL) return;
//CString strName = dlgFile.GetPathName();//获取打开文件文件名(路径)
UpdateData(false);
k.a=k.read(strView);
UpdateData(false);
}
void CRS_110_zhang_SY5Dlg::OnBnClickedButton3Out()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
k.Out(k.a,strOut);
UpdateData(false);
}
创建多个类,层次分明。
使用指针动态开辟数组,较为方便
使用文件操作