实现一个文本文件的解析类(vector,字符串解析的应用)

这是最近做的一个文本解析的类,简单的文件解析,里面一些代码描述了自己当时的一些逻辑想法,以后可以参考。

NCParse.h:

#pragma once
#include <vector>
using namespace std;
#include <string>
#include <fstream>

/* Type define */
typedef unsigned char byte;
typedef unsigned int uint32;

using std::string;
using std::ifstream;
//定义一个NC指令或一个NC注释
//NC指令形如:G00,X100.450, F12000等
//NC注释形如:任意字符信息,不含注释符号
//当NcCode表示一个注释时,需显示地指定bIsComments为TRUE;
class CNcCode
{
public:
	CNcCode();
	CNcCode(LPCTSTR sCode);
	~CNcCode();

public:
	//判断NC程序指令是否有效。以下情况为无效指令
	//sCode为空
	//sCode不是正确的NC指令,且没有指定为注释
	BOOL isValid();

	//返回NC指令的的命令码,如:
	//sCode为G01时,返回 'G',当sCode为X100.450时,返回 'X',当sCode为注释时,返回0。
	TCHAR Code();	

	//返回NC指令的的指令值,如:
	//sCode为G01时,返回 01,当sCode为X100.450时,返回 100.450,当sCode为注释时,返回sCode本身。
	CString Value();

public:
	//存储一个NC指令或一个NC注释
	CString sCode;
	//表示是否为注释
	BOOL bIsComments;
};

//定义多个CNcCode对象集合
typedef vector<CNcCode> tNCCODES;

//定义一个NC程序行对象
class CNcLine
{
public:
	CNcLine();
	~CNcLine();

public:
	//解析NC行,解析结果存放在vtCodes中
	BOOL ParseNcLine(CString sLine);

	//判定是否为纯注释行
	BOOL IsCommentsLine();	

public:
	//构建NC程序行
	//按vtCodes中的顺序输出字符串,NcCode间以空格分割,
	//注释放在最后,与最后一个Nc指令以空格分开,用括弧括起来,
	//当有多个NcCode均为注释时,放在同一个括弧里面
	CString BuildLine();
	
public:
	tNCCODES vtCodes;

};

//定义多个CNcLine集合
typedef vector<CNcLine> tNCLINES;

//定义一个NC程序对象
class CNcProg
{
public:
	CNcProg();
	~CNcProg();

public:
	//添加一个NC程序行
	//如果ncLine中存在相同类别的NC指令,分行添加,如:
	/*
	G54 G00 X100
	处理为:
	G54
	G00 X100

	M310 M311
	处理为:
	M310
	M311
	*/
	void AddNcLine(CNcLine ncLine);
	//添加多个NC程序行
	void AddNcLines(tNCLINES ncLines);

public:
	tNCLINES vtLines;
};

//NC程序解析对象
class CNcParse
{
public:
	CNcParse(void);
	~CNcParse(void);

public:
	//初始化,从配置文件载入以下数据:
	//载入m_CodesBefore的数据
	//载入m_CodesAfter的数据
	//载入m_nStartNum和m_nNcStep
	//载入m_vtCodes4Del的数据
	void Init();

public:
	//将lpIn中的文件按要求解析,转换,并保存到lpOut
	//保存的NC文件中的前几行以纯注释的形式保存原NC文件信息:
	//第1行: lpIn的完整路径,
	//第2行: lpIn的MD5数值存储起来
	long DoParse(CString lpIn, CString lpOut);	//该函数的实现部分包含了主要的逻辑流程。

public:
	//从文件lpfile中的文件头解析出MD5值
	static CString ParseMD5(LPCTSTR lpfile);
	
	//计算lpfile的MD5值
	static CString CalcMD5(LPCTSTR lpfile);

	//获取不正确的指令

private:
	//将ncLine中不支持的指令去除,不支持的指令保存在m_vtCodes4Del中
	void DelCodes(CNcLine& ncLine);

	//如果ncLine中包含有m_CodesBefore[n].code指令,则在返回m_CodesBefore[n].codes
	//存在多个,合并返回
	tNCLINES GetCodesBefore(CNcLine ncLine);

	//如果ncLine中包含有m_CodesAfter[n].code指令,则在返回m_CodesBefore[n].codes
	//存在多个,合并返回
	tNCLINES GetCodesAfter(CNcLine ncLine);

	//校验NC起始符号,即%
	//遍历m_NcProg中正式NC程序段开始前是否存在%行,如果不存在,则在正式NC程序段开始前插入一行%指令
	/*
	正式NC程序段开始位置的界定:
	(*注释段1*)
	(*注释段2*)
	(*注释段3*)

	(*注释段4*)
	G54
	G00 X0 Y0 Z0
	....

	上面的G54即为正式的NC程序开始位置,因为在之前出现的全都是纯注释段,那么这里就应该这么加:
	(*注释段1*)
	(*注释段2*)
	(*注释段3*)

	(*注释段4*)
	%
	G54
	G00 X0 Y0 Z0
	....
	*/
	void CheckStartCode();

	//校验程序号,即Pxxxxxx
	//遍历m_NcProg中起始符号之后到正式NC程序段开始前是否存在NC程序号段,如果不存在,则在正式NC程序段开始前插入一行NC程序段号
	//如果存在的程序短号是以O字母大头的,将O字母替换为P字母
	/*
	正式NC程序段开始位置的界定:
	(*注释段1*)
	(*注释段2*)
	(*注释段3*)
	%
	(*注释段4*)
	G54
	G00 X0 Y0 Z0
	....

	上面的G54即为正式的NC程序开始位置,因为在之前出现的全都是纯注释段,那么这里就应该这么加:
	(*注释段1*)
	(*注释段2*)
	(*注释段3*)
	%
	(*注释段4*)
	Pxxxxxx
	G54
	G00 X0 Y0 Z0
	....
	*/
	void CheckProgNum();

	//给NC程序段重新编号
	//除%,程序程序号行,纯注释行之外的NC程序段必须有行号,即Nxxxx
	//遍历m_NcProg中所有的CNcLine,如果该NcLine中不存在Nxxxx指令,咋在CNcLine的开头插入Nxxxx指令
	//Nxxxxx的指令从m_nStartNum开始,按照m_nNcStep递增
	//实例:假设m_nStartNum = 100,m_nNcStep = 10
	/*
	(*注释段1*)
	(*注释段2*)
	(*注释段3*)
	%
	(*注释段4*)
	Pxxxxxx
	G54
	G00 X0 Y0 Z0
	(注释行)
	M30

	上面的G54即为正式的NC程序开始位置,因为在之前出现的全都是纯注释段,那么这里就应该这么加:
	(*注释段1*)
	(*注释段2*)
	(*注释段3*)
	%
	(*注释段4*)
	Pxxxxxx
	N100 G54
	N110 G00 X0 Y0 Z0
	N120 (注释行)
	N130 M30
	*/
	void ReNumber();

private:
	CNcProg m_NcProg;

	
private:
	struct CODESEXT_t{
		CNcCode code;
		tNCLINES lines;
	};

	vector<CODESEXT_t>	m_CodesBefore;	//需要在之前附加的指令
	vector<CODESEXT_t>	m_CodesAfter;	//需要在之后附加的指令
	tNCCODES			m_vtCodes4Del;	//不支持的NC指令,需要删除

private:
	UINT		m_nStartNum;
	UINT		m_nNcStep;
	
};

/* MD5 declaration. */
class MD5 {
public:
	MD5();
	MD5(const void* input, size_t length);
	MD5(const string& str);
	MD5(ifstream& in);
	void update(const void* input, size_t length);
	void update(const string& str);
	void update(ifstream& in);
	const byte* digest();
	CString toString();
	void reset();

private:
	void update(const byte* input, size_t length);
	void final();
	void transform(const byte block[64]);
	void encode(const uint32* input, byte* output, size_t length);
	void decode(const byte* input, uint32* output, size_t length);
	string bytesToHexString(const byte* input, size_t length);

	/* class uncopyable */
	MD5(const MD5&);
	MD5& operator=(const MD5&);

private:
	uint32 _state[4]; /* state (ABCD) */
	uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */
	byte _buffer[64]; /* input buffer */
	byte _digest[16]; /* message digest */
	bool _finished;   /* calculate finished ? */

	static const byte PADDING[64]; /* padding for calculate */
	static const char HEX[16];
	enum { BUFFER_SIZE = 1024 };
};

NCParse.cpp:

#include "StdAfx.h"
#include "NCParse.h"

#include <algorithm>
#include <iostream>
using namespace std;

/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21


/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
	(a) += F ((b), (c), (d)) + (x) + ac; \
	(a) = ROTATE_LEFT ((a), (s)); \
	(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
	(a) += G ((b), (c), (d)) + (x) + ac; \
	(a) = ROTATE_LEFT ((a), (s)); \
	(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
	(a) += H ((b), (c), (d)) + (x) + ac; \
	(a) = ROTATE_LEFT ((a), (s)); \
	(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
	(a) += I ((b), (c), (d)) + (x) + ac; \
	(a) = ROTATE_LEFT ((a), (s)); \
	(a) += (b); \
}


const byte MD5::PADDING[64] = { 0x80 };
const char MD5::HEX[16] = {
	'0', '1', '2', '3',
	'4', '5', '6', '7',
	'8', '9', 'a', 'b',
	'c', 'd', 'e', 'f'
};
//
//TCHAR strAppNameTemp[1024];//所有AppName的返回值
//TCHAR strKeyNameTemp[1024];//对应每个AppName的所有KeyName的返回值
//TCHAR strReturnTemp[1024];//返回值
CString a[5000];
CString b[5000];
int num;
CNcCode::CNcCode()
{

}

CNcCode::CNcCode(LPCTSTR sCode)
{

}

CNcCode::~CNcCode()
{

}
BOOL CNcCode::isValid()
{
	if(sCode=="")
	{
		return false;
	}
}
TCHAR CNcCode::Code()
{
	if(sCode=="")
	{
		return 0;
	}
	if (sCode.Find('G')>=0)
	{
		return 'G';
	}
	if (sCode.Find('M')>=0)
	{
		return 'M';
	}
	if (sCode.Find('X')>=0)
	{
		return 'X';
	}
	if (sCode.Find('Y')>=0)
	{
		return 'Y';
	}
	if (sCode.Find('Z')>=0)
	{
		return 'Z';
	}
	if(bIsComments==true)
	{
		return '0';
	}

}

CString CNcCode::Value()
{

	return sCode.Mid(1);
}

//
CNcLine::CNcLine()
{

}

CNcLine::~CNcLine()
{

}


char * wchar2char(const wchar_t* wchar )//多字符转unicode
{
	int bufSize= WideCharToMultiByte(CP_ACP,NULL,wchar,-1,NULL,0,NULL,FALSE);
	cout<<bufSize<<endl;
	char *ps = new char[bufSize];
	WideCharToMultiByte(CP_ACP,NULL,wchar,-1,ps,bufSize,NULL,FALSE);
	return ps;
}


BOOL CNcLine::ParseNcLine(CString sLine)
{
	if (sLine.GetLength()==0)
	{
		return FALSE;
	}
	if (vtCodes.size()!=0)
	{
		vtCodes.clear();
	}
	int ej=0,bj=0,c=0;
	string tempCCre;
	string change;
	CNcCode Ccd;
	CString test;
	change=wchar2char(sLine.GetBuffer());
	while(ej = change.find(" ",bj))
	{
		if (ej<1)
		{
			break;
		}
		tempCCre = change.substr(bj,ej-bj); 
		Ccd.sCode=tempCCre.c_str();
		if(Ccd.sCode.Find('(')!=-1)
		{
			Ccd.bIsComments=TRUE;
		}
		else
		{
			Ccd.bIsComments=FALSE;
		}
		vtCodes.push_back(Ccd);
		bj = ej+1;
		if (bj>=0)
		{
			c=bj;
		} 
		ej=0;
	}
	tempCCre=change.substr(c,change.length()-c);
	Ccd.sCode=tempCCre.c_str();
	if(Ccd.sCode.Find(')')!=-1)
	{
		Ccd.bIsComments=TRUE;
	}
	else
	{
		Ccd.bIsComments=FALSE;
	}
	vtCodes.push_back(Ccd);

	return TRUE;
}

CString CNcLine::BuildLine()
{
	CString Line;
	for (size_t i = 0; i < vtCodes.size(); i++) 
	{
		if (vtCodes.at(i).bIsComments=FALSE)
		{
			Line = Line + vtCodes.at(i).sCode+_T("");
		}
		else
		{
			Line=Line+_T("(") +vtCodes.at(i).sCode+_T(")");
		}

	}
	return Line;
}

BOOL CNcLine::IsCommentsLine()
{
	if (vtCodes.size()==0)
	{
		return FALSE;
	}
	for (int i=0;i<vtCodes.size();i++)
	{
		if (vtCodes[i].sCode.Find('(')==-1)
		{
			return FALSE;
		}
		else
		{
			return TRUE;
		}
		
	}
	return FALSE;
	
}

//
CNcProg::CNcProg()
{

}

CNcProg::~CNcProg()
{

}

void CNcProg::AddNcLine(CNcLine ncLine)
{
	CNcLine line;
	CNcCode code;
	int add=0;
	int val;
	char M[2]={_T('G'),_T('M')};      //此处可以添加 字符,注意添加的时候要及时调整数组大小,数组大小与数据个数一致;
	
	for(int n=0;n<2;n++)
	{
		if(ncLine.vtCodes.size() == 0)
		{
			return;
		}

		vector<CNcCode>::iterator it = ncLine.vtCodes.begin();
		vector<CNcCode>::iterator it_e = ncLine.vtCodes.begin();
		for (;it != ncLine.vtCodes.end();it++)
		{
			if (it->sCode=="")
			{
				break;
			}
			if (it->sCode.Find(M[n])!=-1)
			{
				add++;
			}

		}
		if (add==0)
		{
			continue;
		}
		if (add==1)
		{
			vtLines.push_back(ncLine);
		}
		if (add>=2)
		{
			for(;it_e != ncLine.vtCodes.end();)
			{
				if (it_e->sCode.Find(M[n])!=-1)
				{
					if (add==1)
					{
						vtLines.push_back(ncLine);
						return;
					}
					code.sCode=it_e->sCode;
					code.bIsComments=it_e->bIsComments;
					line.vtCodes.push_back(code);
					vtLines.push_back(line);
					if(code.sCode=it_e->sCode)
					{
						it_e=ncLine.vtCodes.erase(it_e);
					}
					else
					{
						it_e++;
					}
					line.vtCodes.clear();
					--add;
				}
			}

		}
		add=0;
	}
}

void CNcProg::AddNcLines(tNCLINES ncLines)
{
	if (ncLines.size()==0)
	{
		return;
	}
	UINT nCount = ncLines.size();
	for(UINT i=0; i<nCount; i++){
		CNcLine& ncLine = ncLines[i];
		AddNcLine(ncLine);
	}
}

//
CNcParse::CNcParse(void)
{
	m_nStartNum = 100;
	m_nNcStep = 10;
}


CNcParse::~CNcParse(void)
{
}

//void EnumIniFile(LPCTSTR pFilePath, CString strKey)//遍历ini文件节点
//{
//
//	DWORD dwKeyNameSize;//对应每个AppName的所有KeyName的总长度
//	//所有AppName的总长度
//	DWORD dwAppNameSize = GetPrivateProfileString(strKey,NULL,NULL,strAppNameTemp,1024,pFilePath);
//
//	if(dwAppNameSize>0)
//	{
//		TCHAR *pAppName = new TCHAR[dwAppNameSize];
//		int nAppNameLen=0;  //每个AppName的长度
//		for(int i = 0;i<dwAppNameSize;i++)
//		{
//			int j=0;
//			pAppName[nAppNameLen++]=strAppNameTemp[i];
//			if(strAppNameTemp[i]=='\0')
//			{
//
//				OutputDebugString(pAppName);
//				OutputDebugString(_T("/r/n"));
//				dwKeyNameSize = GetPrivateProfileString(strKey,pAppName,NULL,strKeyNameTemp,1024,pFilePath);
//				memset(pAppName,0,dwAppNameSize);
//
//				nAppNameLen=0;
//			}
//		}
//		delete[]pAppName;
//	}
//}

void CNcParse::Init()
{
	
	
	CNcCode cDe;
	CNcCode cDe1;
	CNcCode cDe2;
	CNcLine line;
	CNcLine line1;
	tNCCODES Tncc;
	CString lpPath;
	TCHAR nStartNum[10];
	TCHAR nNcStep[10];
	TCHAR Unknow[1000];
	TCHAR nBefore[500];
	TCHAR nAfter[500];
	string Unk;
	string nBf;
	string nBftemp;
	string nBtem;
	int bj=0;
	int ej=0;
	int d=0,f=0,g=0,h=0,w=0;
	CString BeforeValue[100];
	CString AfterKey[100];
	CString AfterValue[100];
	string tempCCre;
	lpPath="G://vs2010//项目//Change//NCAnalysis.ini";
	//导入配置文件的指令起始值m_nStartNum
	GetPrivateProfileString(_T("base"), _T("NCStartNum"),_T(""), nStartNum,10, lpPath);
	m_nStartNum=_tstoi(nStartNum);               

	//导入配置文件中每行代码的间隔数m_nNcStep
	GetPrivateProfileString(_T("base"), _T("NcStep"),_T(""), nNcStep,10, lpPath);
	m_nNcStep=_tstoi(nNcStep);        

	//导入配置文件的未知指令示例
	GetPrivateProfileString(_T("unknown"), _T("Unknown"),_T(""), Unknow,1000, lpPath);

	Unk=wchar2char(Unknow);
	
	while(ej = Unk.find(";",bj))
	{
		if (ej<1)
		{
			break;
		}
		tempCCre = Unk.substr(bj,ej-bj);
		cDe.sCode=tempCCre.c_str();
		if(cDe.sCode.Find('('))
		{
			cDe.bIsComments=TRUE;
		}
		else
		{
			cDe.bIsComments=FALSE;
		}
		m_vtCodes4Del.push_back(cDe);            
		bj = ej+1;
		ej = 0;
	}

	//导入配置文件的需要在之前附加的指令
	
	GetPrivateProfileString(_T("CodesBefore"),_T("CodesBefore"),_T(""), nBefore,500, lpPath);
	nBf=wchar2char(nBefore);
	while(d = nBf.find(";",f))
	{
		if (d<1)
		{
			break;
		}
		tempCCre = nBf.substr(f,d-f);

		while(g = tempCCre.find(",",h))
		{
			CODESEXT_t Csext;
			if (g<1)
			{
				break;
			}
			nBftemp = tempCCre.substr(h,g-h);
			nBtem=tempCCre.substr(g+1,10);
			Csext.code.sCode=nBftemp.c_str();
			Csext.code.bIsComments=FALSE;
			cDe1.sCode=nBtem.c_str();
			cDe1.bIsComments=FALSE;
			line.vtCodes.push_back(cDe1);
			Csext.lines.push_back(line);

			m_CodesBefore.push_back(Csext);	
			h = g+1;
			g = 0;
			line.vtCodes.clear();
		}         
		f = d+1;
		d = 0;
		h=0;
		
	}
	//导入配置文件的需要在之后附加的指令
	GetPrivateProfileString(_T("CodesAfter"), _T("CodesAfter"),_T(""), nBefore,500, lpPath);
	nBf=wchar2char(nBefore);
	while(d = nBf.find(";",w))
	{
		if (d<1)
		{
			break;
		}
		tempCCre = nBf.substr(w,d-w);

		while(g = tempCCre.find(",",h))
		{
			CODESEXT_t Csext1;
			if (g<1)
			{
				break;
			}
			nBftemp = tempCCre.substr(h,g-h);
			nBtem=tempCCre.substr(g+1,10);
			Csext1.code.sCode=nBftemp.c_str();
			Csext1.code.bIsComments=FALSE;
			cDe2.sCode=nBtem.c_str();
			cDe2.bIsComments=FALSE;
			line1.vtCodes.push_back(cDe2);
			Csext1.lines.push_back(line1);

			m_CodesAfter.push_back(Csext1);         
			h = g+1;
			g = 0;
			line1.vtCodes.clear();
		}         
		w = d+1;
		d = 0;
		h=0;
		
	}
}

long CNcParse::DoParse(CString lpIn, CString lpOut)
{
	//打开NC程序
	int i=0,n=0; 
	CString strText =_T("");
	lpIn=_T("G:\\vs2010\\项目\\Change\\6.anc");
	lpOut=_T("G:\\vs2010\\项目\\Change\\1.anc");
	CStdioFile infile;
	infile.Open(lpIn,CFile::modeRead);
	while (infile.ReadString(strText))
	{
		a[n]=strText;
		n++;
	}
	infile.Close();
	CString sline;
	CNcLine ncLine;
	for (int j=0;j<n;j++)
	{

		//构建NC程序行对象
		ncLine.ParseNcLine(a[j]);

		//去除不支持的指令
		DelCodes(ncLine);

		//在NC程序行之前添加附加指令
		tNCLINES ncLinesBefore = GetCodesBefore(ncLine);

		在NC程序行之后添加附加指令
		tNCLINES ncLinesAfter = GetCodesAfter(ncLine);

		m_NcProg.AddNcLines(ncLinesBefore);
		m_NcProg.AddNcLine(ncLine);
		m_NcProg.AddNcLines(ncLinesAfter);

	}
	//校验NC起始符号
	CheckStartCode();

	//校验程序号
	CheckProgNum();

	//重新NC编号
	ReNumber();

	//保存处理之后的NC文件
	CStdioFile outfile;
	outfile.Open(lpOut,CFile::modeWrite);
	for (int i=0;i<1001;i++)
	{
		CString change;
		change.Format(_T("%s\n"),b[i]);
		outfile.WriteString(change);
	}
	outfile.Close();
	return 0;
}

void CNcParse::DelCodes(CNcLine& ncLine)
{
	vector<CNcCode>::iterator it = ncLine.vtCodes.begin();
	for (;it != ncLine.vtCodes.end();it++)
	{

		for (size_t j=0;j<m_vtCodes4Del.size();j++)
		{
			if (it->sCode==m_vtCodes4Del.at(j).sCode)
			{
				it=ncLine.vtCodes.erase(it);
			}
			if (it->sCode.Find('N')!=-1)
			{
				it=ncLine.vtCodes.erase(it);
			}
		}
		
	}

}

tNCLINES CNcParse::GetCodesBefore(CNcLine ncLine)
{
	tNCLINES lines;
	vector<CNcCode>::iterator it = ncLine.vtCodes.begin();
	for (;it != ncLine.vtCodes.end();it++)
	{
		for (size_t j=0;j<m_CodesBefore.size();j++)
		{

			if (it->sCode==m_CodesBefore[j].code.sCode)
			{
				return m_CodesBefore.at(j).lines;
			}
		}
	}
	return lines;
}

tNCLINES CNcParse::GetCodesAfter(CNcLine ncLine)
{
	tNCLINES ncLines;
	vector<CNcCode>::iterator it = ncLine.vtCodes.begin();
	for (;it != ncLine.vtCodes.end();it++)
	{

		for (int j=0;j<m_CodesAfter.size();j++)
		{
			if (it->sCode==m_CodesAfter[j].code.sCode)
			{
				return m_CodesAfter[j].lines;
			}
			
		}
	}

	return ncLines;
}

//校验NC起始符号
void CNcParse::CheckStartCode()
{
	CNcLine line;
	CNcCode code;
	vector<CNcLine>::iterator it = m_NcProg.vtLines.begin();
	for (;it != m_NcProg.vtLines.end();)
	{
		for (int j=0;j<it->vtCodes.size();j++)
		{
			if (it->vtCodes[j].sCode=='%')
			{
				return;
			}
			else
			{
				if (it->IsCommentsLine())
				{
					++it;
				}
				else
				{
					code.sCode="%";
					code.bIsComments=FALSE;
					line.vtCodes.push_back(code);
					m_NcProg.vtLines.insert(it,line);
				}
			}
		}

	}
}


//校验程序号
void CNcParse::CheckProgNum()
{
	CNcLine line;
	CNcCode code;
	char change[10];
	char change_e[101];

	vector<CNcLine>::iterator it = m_NcProg.vtLines.begin();
	for (;it != m_NcProg.vtLines.end();it++)
	{
		
		for (int j=0;j<it->vtCodes.size();j++)
		{
			if (it->vtCodes[j].sCode.Find(_T('O'))>=0)
			{
				char * ptr = wchar2char(it->vtCodes[j].sCode.GetBuffer());
				for (int i=0;i<100;i++)
				{
					change_e[0]=_T('P');
					change_e[i+1]=ptr[i+1];
				}
				code.sCode=change_e[100];
				line.vtCodes.push_back(code);
				m_NcProg.vtLines.erase(it);
				m_NcProg.vtLines.insert(it,line);
			}


			if (it->vtCodes[j].sCode.Find('P')==-1)
			{
				if (it->vtCodes[j].sCode.Find('G')>=0)
				{
					code.sCode="P11111";
					code.bIsComments=FALSE;
					line.vtCodes.push_back(code);
					m_NcProg.vtLines.insert(it,line);
					return;
				}

			}
			else
			{
				return;
			}
			
			

		}

	}
}

void CNcParse::ReNumber()
{
	
	int w=m_NcProg.vtLines.size();
	num=w;
	CString* c=new CString[w];
	CString* pp=new CString[w];
	
	for (int i=0;i<w;i++)
	{
		for (int j=0;j<m_NcProg.vtLines[i].vtCodes.size();j++)
		{
				pp[i]=pp[i]+_T(" ")+ m_NcProg.vtLines[i].vtCodes[j].sCode;
			
		}
		
	}

	for (int k=0;k<w;k++)
	{
		CString start;
		start.Format(_T("%d"),m_nStartNum);
		CString add=_T("N")+ start+_T(" ") ;
		c[k]=add;
		m_nStartNum+=m_nNcStep;

	}
	for (int k=0;k<w;k++)   //在首行加% 在每行之前加NXXX
	{
		b[k]=pp[k];
		b[k]=c[k]+b[k];

	}
	delete[] c;
	delete[] pp;

}
CString CNcParse::ParseMD5(LPCTSTR lpfile)
{
	
	MD5 md5;
	md5.reset();
	md5.update(ifstream(lpfile));
	return md5.toString();
}


CString CNcParse::CalcMD5(LPCTSTR lpfile)//计算MD5值
{
	MD5 md5;
	md5.reset();
	md5.update(ifstream(lpfile));
	//AfxMessageBox(md5.toString().c_str());
	return md5.toString();

}




/* Default construct. */
MD5::MD5() {
	reset();
}

/* Construct a MD5 object with a input buffer. */
MD5::MD5(const void* input, size_t length) {
	reset();
	update(input, length);
}

/* Construct a MD5 object with a string. */
MD5::MD5(const string& str) {
	reset();
	update(str);
}

/* Construct a MD5 object with a file. */
MD5::MD5(ifstream& in) {
	reset();
	update(in);
}

/* Return the message-digest */
const byte* MD5::digest() {

	if (!_finished) {
		_finished = true;
		final();
	}
	return _digest;
}

/* Reset the calculate state */
void MD5::reset() {

	_finished = false;
	/* reset number of bits. */
	_count[0] = _count[1] = 0;
	/* Load magic initialization constants. */
	_state[0] = 0x67452301;
	_state[1] = 0xefcdab89;
	_state[2] = 0x98badcfe;
	_state[3] = 0x10325476;
}

/* Updating the context with a input buffer. */
void MD5::update(const void* input, size_t length) {
	update((const byte*)input, length);
}

/* Updating the context with a string. */
void MD5::update(const string& str) {
	update((const byte*)str.c_str(), str.length());
}

/* Updating the context with a file. */
void MD5::update(ifstream& in) {

	if (!in) {
		return;
	}

	std::streamsize length;
	char buffer[BUFFER_SIZE];
	while (!in.eof()) {
		in.read(buffer, BUFFER_SIZE);
		length = in.gcount();
		if (length > 0) {
			update(buffer, length);
		}
	}
	in.close();
}

/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5::update(const byte* input, size_t length) {

	uint32 i, index, partLen;

	_finished = false;

	/* Compute number of bytes mod 64 */
	index = (uint32)((_count[0] >> 3) & 0x3f);

	/* update number of bits */
	if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) {
		++_count[1];
	}
	_count[1] += ((uint32)length >> 29);

	partLen = 64 - index;

	/* transform as many times as possible. */
	if (length >= partLen) {

		memcpy(&_buffer[index], input, partLen);
		transform(_buffer);

		for (i = partLen; i + 63 < length; i += 64) {
			transform(&input[i]);
		}
		index = 0;

	} else {
		i = 0;
	}

	/* Buffer remaining input */
	memcpy(&_buffer[index], &input[i], length - i);
}

void MD5::final() {

	byte bits[8];
	uint32 oldState[4];
	uint32 oldCount[2];
	uint32 index, padLen;

	/* Save current state and count. */
	memcpy(oldState, _state, 16);
	memcpy(oldCount, _count, 8);

	/* Save number of bits */
	encode(_count, bits, 8);

	/* Pad out to 56 mod 64. */
	index = (uint32)((_count[0] >> 3) & 0x3f);
	padLen = (index < 56) ? (56 - index) : (120 - index);
	update(PADDING, padLen);

	/* Append length (before padding) */
	update(bits, 8);

	/* Store state in digest */
	encode(_state, _digest, 16);

	/* Restore current state and count. */
	memcpy(_state, oldState, 16);
	memcpy(_count, oldCount, 8);
}

/* MD5 basic transformation. Transforms _state based on block. */
void MD5::transform(const byte block[64]) {

	uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16];

	decode(block, x, 64);

	/* Round 1 */
	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

	/* Round 2 */
	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
	GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

	/* Round 3 */
	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
	HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */

	/* Round 4 */
	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

	_state[0] += a;
	_state[1] += b;
	_state[2] += c;
	_state[3] += d;
}

/* Encodes input (ulong) into output (byte). Assumes length is
a multiple of 4.
*/
void MD5::encode(const uint32* input, byte* output, size_t length) {

	for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
		output[j]= (byte)(input[i] & 0xff);
		output[j + 1] = (byte)((input[i] >> 8) & 0xff);
		output[j + 2] = (byte)((input[i] >> 16) & 0xff);
		output[j + 3] = (byte)((input[i] >> 24) & 0xff);
	}
}

/* Decodes input (byte) into output (ulong). Assumes length is
a multiple of 4.
*/
void MD5::decode(const byte* input, uint32* output, size_t length) {

	for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
		output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) |
			(((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24);
	}
}

/* Convert byte array to hex string. */
string MD5::bytesToHexString(const byte* input, size_t length) {

	string str;
	str.reserve(length << 1);
	for (size_t i = 0; i < length; ++i) {
		int t = input[i];
		int a = t / 16;
		int b = t % 16;
		str.append(1, HEX[a]);
		str.append(1, HEX[b]);
	}
	return str;
}

/* Convert digest to string value */
CString MD5::toString() {
	CString temp;
	temp.Format(_T("%s"),bytesToHexString(digest(), 16).c_str());
	return temp;
}

然后是MFC测试,添加一个按钮,在按钮里面调用测试接口函数:

void CChangeDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	CNcParse pNcParse;
	
	pNcParse.Init();
	pNcParse.DoParse(NULL,NULL);
}

测试结果:

导入文档内容:

G90 G49 G1234 
G40 G1234 G80 
G53 Z0 
G64 
N100 G777 
M07 
M14 M22 
M22 
M18
H50 H60
M139 
M65 
G888
M71
M73 
 
M6T01 
M37P1 
G54 
M11 
M175 
M03 S18000 
G90 G0 G43 H1 
X456. Y456. 
Z50. 
Z30. 
G1 Z-5. F3600 
Y312.546 F5000 
X304.826 
Y456. 
X456. 
G0 Z50. 
M05 
M14 
M176 
M37 P0 
G53 Z0. 
 
M17 
M21 
M19 
M37P2 
G54 
G90 G0 G43 H9 
X0. Y250.  
Z50. 
Z30. 
G1 Z-5. F3600 
X500. F7200 
G0 Z50. 
M37 P0 
G53 Z0 
 
M17 
M21 
M20 
M37P3 
G54 
G90 G0 G43 H9 
X250. Y500. 
Z50. 
Z30. 
G1 Z-5. F4000 
Y0. F9000 
G0 Z50. 
M22  
M18 
M37 P0 
G53 Z0 

M37 P11   
G54 
G0 G90 G43 H19 
M128 
M138 
M140 
M111 

G0 X50. Y50. 
Z30. 
G1 Z-5. F4000 
G0 Z50. 
M139 
M129 
M140 
M37 P0 
G53 Z0 
 
M17 
M66 
M63 S2=18000 
G53 Z0 
M19 
M37 P6 
G54 
G90 G0 G43 H10 
X100. Y-230. 
Z-9. 
Y-210. 
G1 Y-175. F3600 
X200. F7200 
G0 Y-230. 
M64 
M65 
M22 
M18 
M37 P0 
G53 Z0. 
M16 
M70 
M72 
G53 Y0. 
M30 

导出文档内容为:

N100  %
N101  P11111
N102  G90
N103  G49 
N104  G40
N105  G80 
N106  G53 Z0 
N107  G64 
N108  G55 F200
N109  G777 
N110  M07 
N111  M14
N112  M22 
N113  M22 
N114  M18
N115  M139 
N116  M65 
N117  G55 F200
N118  G888
N119  G55 F210
N120  M71
N121  M73 
N122  M6T01 
N123  M37P1 
N124  G54 
N125  M11 
N126  M175 
N127  M03 S18000 
N128  G90
N129  G0
N130  G43 H1 
N131  G1 Z-5. F3600 
N132  G0 Z50. 
N133  M05 
N134  M14 
N135  M176 
N136  M37 P0 
N137  G53 Z0. 
N138  M17 
N139  M21 
N140  M19 
N141  M37P2 
N142  G54 
N143  G90
N144  G0
N145  G43 H9 
N146  G1 Z-5. F3600 
N147  G0 Z50. 
N148  M37 P0 
N149  G53 Z0 
N150  M17 
N151  M21 
N152  M20 
N153  M37P3 
N154  G54 
N155  G90
N156  G0
N157  G43 H9 
N158  G1 Z-5. F4000 
N159  G0 Z50. 
N160  M22  
N161  M18 
N162  M37 P0 
N163  G53 Z0 
N164  G53 Z0 
N165  M37 P11   
N166  G54 
N167  G0
N168  G90
N169  G43 H19 
N170  M128 
N171  M138 
N172  M140 
N173  M111 
N174  M111 
N175  G0 X50. Y50. 
N176  G1 Z-5. F4000 
N177  G0 Z50. 
N178  M139 
N179  M129 
N180  M140 
N181  M37 P0 
N182  G53 Z0 
N183  M17 
N184  M66 
N185  M63 S2=18000 
N186  G53 Z0 
N187  M19 
N188  M37 P6 
N189  G54 
N190  G90
N191  G0
N192  G43 H10 
N193  G1 Y-175. F3600 
N194  G0 Y-230. 
N195  M64 
N196  M65 
N197  M22 
N198  M18 
N199  M37 P0 
N200  G53 Z0. 
N201  M16 
N202  M70 
N203  M72 
N204  G53 Y0. 
N205  M30 

功能实现需求:

  1. 转移细节说明

NC文本中小括号为注解符号

  • 首行加上:%

每一行首字段前加Nxxx,其中xxx规则为可配置,如m_nStartNum = 100,m_nNcStep = 10

则是以100开始以10递增,如:

    N100 G54

N110 G00 X0 Y0 Z0

N120 (注解内容)

N130 M30

如原有NC代码行中已有N120,需要将其重新替换

  • 需要在某指令之前或者之后附加指令(可配置参数)

如需要在G888前加G55 F200

原:

G888 X20.0

解析为:

Nxxx G55 F200

Nxxx G888 X20.0

如需要在G999后加G55 F200

原:

G999 X20.0

解析为:

Nxxx G999 X20.0

Nxxx G55 F200

 

  • 如果同一行中有相同指令需要解析为分行。

如:

G54 G00 X100

解析为:

Nxxx G54 

Nxxx G00 X100

 

M310 M311

解析为:

Nxxx M310

Nxxx M311

  • 去除不支持的指令

   可配置,从配置文件中读取

如G1234,被配置为不可识别,则将本指令解析为删除

 

  • 配置文件格式NCAnalysis.ini

[base]

NCStartNum = 100

NcStep = 10

[unknown]

Unknown=G1234;G2345;G678

[CodesBefore]

CodesBefore=G888,G55 F200;G777,G55 F200;G999,G22 F111

[CodesAfter]

CodesAfter=G888,G55 F200;G777,G55 F200;G999,G22 F111

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值