这是最近做的一个文本解析的类,简单的文件解析,里面一些代码描述了自己当时的一些逻辑想法,以后可以参考。
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
功能实现需求:
- 转移细节说明
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