用VC读取和分析格式化文本配置文件

简介:
大多数的应用程序都有需要配置的参数,配置参数的保存有多种方法,比如采用数据库保存、二进制文件保存、格式化的文本文件保存,各有优缺点,对于一般小的安全性要求不高应用程序,推荐采用格式化文本文件保存方式,这样可以节约编辑修改的界面编程,使用记事本程序编辑即可。
  早期的windows就是采用的INI格式文本文件。现在很多应用程序包括大型的软件也还在采用格式化文本文件保存配置参数,比如Bentely MicroStation GIS平台GEOGRAPHICS8.0。
  本文给出的就是利用VC来读取和分析配置文本文件,这是笔者这消防监控系统远程终端软件使用的方法。同时给出一个C++类来封装配置文本文件的读取分析。
  下面是我采用的配置文件的例子,包含单个参数定义,表格参数定义,注释:


// 协议名称: TL
// 工程: SQ
// 配置人: JY
#DEFINE_BEGIN //以下为常量定义

//通信参数
@COM_PORT \\.\COM1 //COM口
@COM_BAUDRATE 1200 //波特率
@COM_BITSIZE 8 //数据位 number of bits/byte, 4-8
@COM_STOPBIT 0 // 0,1,2 对应 1, 1.5, 2
@COM_PARITY 0 //0-4对应no,odd,even,mark,space 
@STATIONNO 0 //终端号
@TCPIP_SERVERIP 192.168.0.10 //服务器IP地址
@TCPIP_PORTNO 3024 //端口

#DEFINE_END


#TABLE_BEGIN //表格
//编号 识别字符串 
//例子如下
0 Ion Detector, ALU1, L1S43 //测量台2#离子烟感探测器 报警
1 Thermal Det, ALU1, L1S39 //值班室温感探测器报警

#TABLE_END


语法解释:
// 单行注释
#DEFINE_BEGIN 单个参数定义的开始标记
#DEFINE_END 单个参数定义的结束标记
#TABLE_BEGIN 表格参数开始标记
#TABLE_END 表格参数结束标记

单个参数的配置:
每个参数一行:以空格、TAB制表符作为分隔,注释可选,每行结束后有Enter键换行。
表格参数配置:第一列为数字编号,作为ID用,第一列和第二列之间采用空格、TAB制表符作为分隔,其他列之间采用','逗号、空格、TAB制表符分隔,因此从第二列起,字符串中间夹的空格是有效字符。比如上面例子中的第一行解释如下:
"0","Ion Detector","ALU1","L1S43"
同样,表格参数也是每行有Enter键换行。
下面给出一个C++类来完成这个格式的文本配置读取和分析。

规模:
文本文件的大小:<48kbytes
单个参数定义个数:不限
表格参数定义: 100行 X 4列 
这些规模大小可以修改下面的宏定义来满足你的需要

#define TABLE_MAXROW 100
#define TABLE_MAXCOL 5 //含索引ID列
typedef struct{
int nID;
char s[TABLE_MAXCOL-1][64];

}TAG_TABLEREC,*LPTABLEREC;

class CDataTxt
{
public:
CDataTxt();
~CDataTxt();
CString m_szPath;//配置文件全路经名

BOOL Read();//读入文件
BOOL GetDefine(LPCTSTR lpszName,CString &szVal);//获取定义

//{{TABLE
TAG_TABLEREC m_Table[TABLE_MAXROW];
int m_nRows;
//}}
private: 
char m_cbuf[1024*48];
int m_nBufSize;//=1024*48;
int m_nDataSize;
CString m_szDefine;//定义段
int m_nDefineLen;
CString m_szTable;//表格段
int m_nTableLen;
void DelNote();//去掉注释
void FormatTable(void);//规格化表格
};

CDataTxt::CDataTxt()
{
int i;
m_szPath="SQTL.txt";
m_nBufSize=1024*48;
m_nDataSize=0;
m_nDefineLen=0;
m_nTableLen=0;

for(i=0;i<m_nBufSize;i++)
m_cbuf =0;
ZeroMemory(&m_Table,sizeof(m_Table));
m_nRows=0;

}
CDataTxt::~CDataTxt()
{

}
BOOL CDataTxt::Read()
{
CFile fl;
if(!fl.Open(m_szPath,CFile::modeRead|CFile::typeBinary))
return FALSE;
DWORD dwl=fl.GetLength();
if(dwl > (DWORD)m_nBufSize)
dwl=(DWORD)m_nBufSize;
m_nDataSize=(int)(fl.Read(m_cbuf,dwl));
fl.Close();
DelNote();//去掉注释
return TRUE;
}

void CDataTxt::DelNote()//去掉注释,分成定义段和表格段
{
CString szt="";
char cc,ccp=0;
int i;
for(i=0;i<m_nDataSize;i++)
{
cc=m_cbuf;
if(cc != '/'){ szt+=cc;ccp=cc; }
else//cc=='/'
{
if(i<m_nDataSize)
{
if(m_cbuf[i+1]=='/')//注释开始
{
while((i<m_nDataSize)&&(m_cbuf!=0x0d)) i++;
if(m_cbuf==0x0d) i--;
ccp=0;
}
else{szt+=cc; ccp=cc; }
}
}
}
m_nDataSize=szt.GetLength();
sprintf(m_cbuf,"%s",szt);
int ns=szt.Find("#DEFINE_BEGIN",0);
int ne=szt.Find("#DEFINE_END",0);
if((ns==-1)||(ne==-1)) return;
ns+=13;
m_szDefine="";
for(i=ns;i<ne;i++) m_szDefine+=szt;
m_nDefineLen=m_szDefine.GetLength();
ns=szt.Find("#TABLE_BEGIN",0);
ne=szt.Find("#TABLE_END",0);
ns+=12;
if((ns==-1)||(ne==-1)) return;
m_szTable="";
for(i=ns;i<ne;i++) m_szTable+=szt;
m_nTableLen=m_szTable.GetLength();
FormatTable();//规格化表格
}

BOOL CDataTxt::GetDefine(LPCTSTR lpszName,CString &szVal)//获取定义
{
CString szName=lpszName;
if(szName.IsEmpty()) return FALSE;
int nLen=szName.GetLength();
int ns=m_szDefine.Find(lpszName,0);
if(ns==-1) return FALSE;
szVal="";
int i=ns+nLen;
BOOL bStartCopy=FALSE;
char cc;
while(i<m_nDefineLen)
{
cc=m_szDefine;
if((cc!=0x0D)&&(cc!=0x0A)&&(cc!='\t')&&(cc!=0x20))
{
if(bStartCopy==FALSE) bStartCopy=TRUE;
szVal+=m_szDefine;
}
else{if(bStartCopy) break;} i++;
}
return TRUE;
}

void CDataTxt::FormatTable()//规格化表格
{
int i=0;
char cc;
int nRow=0;
CString szLine="",szID="",szVal="",szCol="";
int nCol=0;
while(i<m_nTableLen)
{
cc=m_szTable;
if((cc==0x0A)||(cc=='\t')) cc=0x20;
if(cc==0X0D)//处理一行
{
szLine.TrimLeft(); szLine.TrimRight();
if(!szLine.IsEmpty())
{
int nl=szLine.GetLength();
int j;
char c;
szID="";
for(j=0;j<nl;j++)//取szID
{
c=szLine[j];
if(c==0x20)
break;
szID+=c;
}
m_Table[nRow].nID=atoi(szID);
BOOL bStart;
bStart=FALSE;
szVal="";
while(j<nl)//取szCols
{
c=szLine[j];
if((bStart==FALSE)&&(c==0x20)) j++;
else{bStart=TRUE;szVal+=c;j++;}
}
szVal.TrimLeft();szVal.TrimRight();
nCol=0; nl=szVal.GetLength();
j=0;szCol="";
while(j<nl)
{
c=szVal[j];
if(c==',')
{
if(szCol.IsEmpty()) break;
else
{
if(nCol < TABLE_MAXCOL-1)
{
if(szCol.GetLength() <64)
sprintf(&(m_Table[nRow].s[nCol][0]),"%s",szCol);
nCol++; TRACE("szCol=%s\n",szCol);
}
}
szCol="";
}
else szCol+=c;
j++;
}
if(!szCol.IsEmpty())
{
if(nCol < TABLE_MAXCOL-1)
{
if(szCol.GetLength() <64)
sprintf(m_Table[nRow].s[nCol],"%s",szCol);
nCol++; TRACE("szCol=%s\n",szCol);
}
}
if(nCol>0)
nRow++;
if(m_nRows >=TABLE_MAXROW)
{
m_nRows=nRow;
return;
}
szLine="";
}
}
else szLine+=cc;
i++;
}
m_nRows=nRow;
}

void test()
{
CDataTxt dt;
dt.m_szPath="c:\\sqtl.txt";
dt.Read();
CString szVal,szMsg;
if(dt.GetDefine("@COM_PORT",szVal)){TRACE("@COM_PORT=%s\n",szVal);}
if(dt.GetDefine("@COM_BAUDRATE",szVal)){TRACE("@COM_BAUDRATE=%s\n",szVal);}
int i;
for(i=0;i<dt.m_nRows;i++)
{
TRACE("Row=%d,ID=%d,s[0]=%s,sz[1]=%s,s[2]=%s,s[3]=%s\n",
i,
dt.m_Table.nID,
&(dt.m_Table.s[0][0]),
&(dt.m_Table.s[1][0]),
&(dt.m_Table.s[2][0]),
&(dt.m_Table.s[3][0]));

}
}


  文件读取:
void CShotdetect::WritetoText(int p1, LONGLONG p2)
{
CString str;
str = "c:\\文本文件.txt";
CFile file;
file.Open(str,CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate);
char ch_str1[30];
char ch_str2[20];
_itoa(p1,ch_str1,10);
strcat(ch_str1,",");
_itoa(p2,ch_str2,10);
strcat(ch_str1,ch_str2);
strcat(ch_str1,"\n");
int length = 0;
for(int i = 0;i<30;i++)
{
if(ch_str1!='\0')
length++;
else
break;
}
file.SeekToEnd();
file.Write(ch_str1,length);
file.Close();










本文转自 life0 51CTO博客,原文链接:http://blog.51cto.com/life0/12412,如需转载请自行联系原作者
目录
相关文章
|
2月前
MFC编程 -- 保存和读取列表框内容
MFC编程 -- 保存和读取列表框内容
16 0
|
4月前
EndNote文献输出引用格式自定义修改与编辑界面解读
EndNote文献输出引用格式自定义修改与编辑界面解读
|
Java Maven Windows
关于win11系统中环境变量path的显示和编辑格式变成一行的问题
关于win11系统中环境变量path的显示和编辑格式变成一行的问题
1340 0
关于win11系统中环境变量path的显示和编辑格式变成一行的问题
Goland 开启文件保存自动进行格式化 的两种方式
Goland 开启文件保存自动进行格式化 的两种方式
Goland 开启文件保存自动进行格式化 的两种方式
|
C语言
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
220 0
|
C++
提示编码有问题时,VS保存选项
提示编码有问题时,VS保存选项
52 0
|
Java
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
208 0
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
|
Java
编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内
编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内
230 0
编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内
GoLand:设置gofmt与goimports,保存时自动格式化代码
GoLand:设置gofmt与goimports,保存时自动格式化代码
828 0
GoLand:设置gofmt与goimports,保存时自动格式化代码