用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月前
|
PyTorch TensorFlow API
大模型中 .safetensors 文件、.ckpt文件、.gguf和.pth以及.bin文件区别、加载和保存以及转换方式
本文讨论了大模型中不同文件格式如`.safetensors`、`.ckpt`、`.gguf`、`.pth`和`.bin`的区别、用途以及如何在TensorFlow、PyTorch和ONNX等框架之间进行加载、保存和转换。
357 2
文件打开的格式
文件打开的格式
|
6月前
|
图形学
【unity小技巧】unity读excel配置表操作,excel转txt文本,并读取txt文本内容,实例说明
【unity小技巧】unity读excel配置表操作,excel转txt文本,并读取txt文本内容,实例说明
198 0
|
7月前
MFC编程 -- 保存和读取列表框内容
MFC编程 -- 保存和读取列表框内容
86 1
ENVI_IDL:(批量处理)如何对HDF5文件进行GLT文件的创建并进行几何校正最终输出为IMG格式?
ENVI_IDL:(批量处理)如何对HDF5文件进行GLT文件的创建并进行几何校正最终输出为IMG格式?
185 0
|
存储 编解码
ENVI_IDL:读取OMI数据(HDF5)并输出为Geotiff文件+详细解析
ENVI_IDL:读取OMI数据(HDF5)并输出为Geotiff文件+详细解析
413 1
|
C语言
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
262 0
|
C++
提示编码有问题时,VS保存选项
提示编码有问题时,VS保存选项
74 0
根据用户输入的参数自动读取对应时间内的wrf模式输出数据
根据用户输入的参数自动读取对应时间内的wrf模式输出数据
|
Java
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
256 0
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中