• C/C++程序使用lu对象作为配置文件


    1 说明

        要演示本文的例子,你必须下载Lu32脚本系统。本文的例子需要lu32.dll、lu32.lib、C格式的头文件lu32.h,相信你会找到并正确使用这几个文件。

        用C/C++编译器创建一个控制台应用程序,复制本文的例子代码直接编译运行即可。

    2 使用lu对象作为配置文件的格式

        通常应用程序会有一些可调控的参数,简单的控制可以通过命令行参数来实现,然而复杂一些的则一般会使用配置文件的形式。本文讨论使用lu对象作为配置文件的格式及实现。关于lu对象,参考Lu用户指南;lu对象的数据结构参考Lu编程指南

        lu对象中的基本数据格式采取“键 : 值”的方式,键是以#开头的字符串,而值可为任意数据(本文代码支持的数据类型有lu对象、编译符#、逻辑值、nil、字符串、整数、实数)。例如:

    [cpp] view plaincopy
    1. (:static)= global(true), static=  
    2. lu{  
    3.     ... ... ,  
    4.     #name : "王刚",  
    5.     #age : 21,  
    6.     ... ...  
    7. }  


        这是个无名函数,可以避免函数重名问题;函数 global(true) 使得lu对象成为全局对象,故通常要使用该函数;static是一个静态变量,将全局的lu对象保存在静态变量中可以避免被垃圾收集器回收。

        lu对象可以嵌套,故可存储类似“键1 : 键2 : 键3 : 值”的数据,第1个键在第1层lu对象中,第2个键在第2层lu对象中,依此类推。例如:

    [cpp] view plaincopy
    1. (:static)= global(true), static=  
    2. {  
    3.   "--- 使用字符串进行注释 ---" ,  
    4.   ... ... ,  
    5.   #生产部 : lu{  
    6.       #staff : lu{  
    7.           #王刚 : lu{  
    8.               #age : 21,  
    9.               #性别 : "男",  
    10.               #工作量 : lu{11, 15},  
    11.               #e_mail : "wanggang@sina.com"  
    12.           },  
    13.           #李军 : lu{  
    14.               #age : 25,  
    15.               #性别 : "男",  
    16.               #工作量 : lu{17, 1.2, 1.8},  
    17.               #website : "http://www.lijun.net/"  
    18.           }  
    19.       }  
    20.   },  
    21.   ... ...  


        本例中李军的年龄可表示为“#生产部 : #staff : #李军 : #age : 25”,而李军的工作量是一个lu对象“#生产部 : #staff : #李军 : #工作量 : lu{17, 1.2, 1.8}”。

        另外,Lu核心库支持的表达式中不能有注释,不过可以使用字符串作为注释,如上例。使用字符串作为注释的好处是:当我们重建配置文件时,注释仍然存在。

        程序对配置文件的操作有三种:读配置文件,修改配置文件,写配置文件。在本文的例子中,读配置文件即编译一个返回lu对象(包含配置信息)的字符串表达式;修改配置文件即对该lu对象的成员进行存取;写配置文件即根据该lu对象生成相应的字符串表达式。

        本文的代码中提供了3个实用的函数lu2str、getlumember、setlumember以更方便地操作lu对象,包含了完整的错误检查,故代码较长。

    3 代码

    [cpp] view plaincopy
    1. #include <stdio.h>  
    2. #include <string.h>  
    3. #include <locale.h>  
    4. #include "lu32.h"  
    5.   
    6. #pragma comment( lib, "lu32.lib" )  
    7.   
    8. //输出lu对象到一个字符串,支持lu对象、编译符#、逻辑值、nil、字符串、整数、实数  
    9. int lu2str(LuData *pVal,wchar_t *luStr,int luStrMax,int *luStrNow)  
    10. {  
    11.     luLu *plu;  //lu对象指针  
    12.     static luLu *pmainlu=NULL;  //记住最初的lu对象,避免该函数无穷递归调用  
    13.     static int kkk;  
    14.     int j;  
    15.     luVOID i,StrMax;  
    16.     luINT k;  
    17.     wchar_t *pStr;  
    18.     char str32[32];  
    19.     int bBlank = 1, bKeyLu = 0;  
    20.   
    21.     if(pVal->BType!=luDynData_lu) return 1;  //无效的lu对象  
    22.     //验证lu对象是否有效  
    23.     plu=(luLu *)SearchKey((char *)&(pVal->x), sizeof(luVOID), luDynData_lu);  
    24.     if(NULL==plu) return 1; //无效的lu对象指针  
    25.     if(plu==pmainlu) return 2;  //递归嵌套的lu对象  
    26.     if(pmainlu==NULL)  
    27.     {  
    28.         pmainlu=plu;    //记住最初的lu对象  
    29.         if(luStrMax<40) return 3;    //缓冲区太小  
    30.         wcscpy_s(luStr,luStrMax,L"(:static)= global(true), static= lu{ ");  
    31.         *luStrNow=39;  
    32.     }  
    33.   
    34.     kkk++;  
    35.   
    36.     for(i=0;i<plu->Len;i++)  
    37.     {  
    38.         if(plu->Lu[i].BType==luStaData_struniint || plu->Lu[i].BType==luDynData_lu) bKeyLu=1;  
    39.     }  
    40.     if(bKeyLu==0)  
    41.     {  
    42.         if(luStr[*luStrNow-1]==' ') (*luStrNow)--;  
    43.         if(luStr[*luStrNow-1]==' ') (*luStrNow)--;  
    44.         if(luStr[*luStrNow]) luStr[*luStrNow]='';  
    45.     }  
    46.     for(i=0;i<plu->Len;i++)  
    47.     {  
    48.         if(bKeyLu==0)  
    49.         {  
    50.             bBlank = 0;  
    51.             if(luStr[*luStrNow-1]==' ') (*luStrNow)--;  
    52.             if(luStr[*luStrNow-1]==' ') (*luStrNow)--;  
    53.             if(luStr[*luStrNow]) luStr[*luStrNow]='';  
    54.         }  
    55.         if(bBlank)  
    56.         {  
    57.             if(luStrMax-(*luStrNow)<kkk*4)  
    58.             {  
    59.                 kkk--; return 3;    //缓冲区太小  
    60.             }  
    61.             for(j=0;j<kkk*4;j++) luStr[(*luStrNow)++]=' ';  
    62.             luStr[*luStrNow]='';  
    63.         }  
    64.         else  
    65.         {  
    66.             bBlank = 1;  
    67.         }  
    68.   
    69.         switch(plu->Lu[i].BType)  
    70.         {  
    71.         case luStaData_nil :    //nil  
    72.             if(luStrMax-(*luStrNow)<5)  
    73.             {  
    74.                 kkk--; return 3;    //缓冲区太小  
    75.             }  
    76.             wcscat_s(luStr,luStrMax,L"nil");  
    77.             *luStrNow=*luStrNow+3;  
    78.             break;  
    79.         case luStaData_int64 :  //整数  
    80.             j=sprintf_s(str32,32,"%I64d",plu->Lu[i].x);  
    81.             if(j<0)  
    82.             {  
    83.                 kkk--; return 4;    //数据转换错误  
    84.             }  
    85.             if(luStrMax-(*luStrNow)<j)  
    86.             {  
    87.                 kkk--; return 3;    //缓冲区太小  
    88.             }  
    89.             for(j=0;str32[j];j++) luStr[(*luStrNow)++]=str32[j];  
    90.             luStr[*luStrNow]='';  
    91.             break;  
    92.         case luStaData_double : //实数  
    93.             j=sprintf_s(str32,32,"%f",*(double *)&(plu->Lu[i].x));  
    94.             if(j<0)  
    95.             {  
    96.                 kkk--; return 4;    //数据转换错误  
    97.             }  
    98.             if(luStrMax-(*luStrNow)<j)  
    99.             {  
    100.                 kkk--; return 3;    //缓冲区太小  
    101.             }  
    102.             for(j=0;str32[j];j++) luStr[(*luStrNow)++]=str32[j];  
    103.             luStr[*luStrNow]='';  
    104.             break;  
    105.         case luStaData_logical :    //逻辑值  
    106.             if(luStrMax-(*luStrNow)<8)  
    107.             {  
    108.                 kkk--; return 3;    //缓冲区太小  
    109.             }  
    110.             if(plu->Lu[i].x)  
    111.             {  
    112.                 wcscat_s(luStr,luStrMax,L"true");  
    113.                 *luStrNow=*luStrNow+4;  
    114.             }  
    115.             else  
    116.             {  
    117.                 wcscat_s(luStr,luStrMax,L"false");  
    118.                 *luStrNow=*luStrNow+5;  
    119.             }  
    120.             break;  
    121.         case luStaData_struniint :  //由字符串决定的唯一整数  
    122.             pStr=(wchar_t *)UniIntToStr((luVOID)plu->Lu[i].x,&k);  
    123.             if(!pStr)  
    124.             {  
    125.                 kkk--; return 4;    //数据转换错误  
    126.             }  
    127.             k=k/2;  
    128.             if(luStrMax-(*luStrNow)<=k)  
    129.             {  
    130.                 kkk--; return 3;    //缓冲区太小  
    131.             }  
    132.             luStr[(*luStrNow)++]='#';  
    133.             for(j=0;j<(int)k;j++) luStr[(*luStrNow)++]=pStr[j];  
    134.             luStr[*luStrNow]='';  
    135.             break;  
    136.         case luStaData_string :     //静态字符串  
    137.         case luDynData_string :     //动态字符串  
    138.             pStr=GetStr(plu->Lu+i,NULL,&StrMax);  
    139.             if(!pStr)  
    140.             {  
    141.                 kkk--; return 4;    //数据转换错误  
    142.             }  
    143.             if(luStrMax-(*luStrNow)<2)  
    144.             {  
    145.                 kkk--; return 3;    //缓冲区太小  
    146.             }  
    147.             luStr[(*luStrNow)++]='"';  
    148.             for(j=0;j<pStr[j];j++)  
    149.             {  
    150.                 if(luStrMax-(*luStrNow)<=3)  
    151.                 {  
    152.                     kkk--; return 3;    //缓冲区太小  
    153.                 }  
    154.                 switch(pStr[j])  
    155.                 {  
    156.                     case '\' :  
    157.                     case '"' :  
    158.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]=pStr[j];  
    159.                         break;  
    160.                     case 'a' :  
    161.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]='a';  
    162.                         break;  
    163.                     case '' :  
    164.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]='b';  
    165.                         break;  
    166.                     case 'f' :  
    167.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]='f';  
    168.                         break;  
    169.                     case ' ' :  
    170.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]='n';  
    171.                         break;  
    172.                     case ' ' :  
    173.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]='r';  
    174.                         break;  
    175.                     case ' ' :  
    176.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]='t';  
    177.                         break;  
    178.                     case 'v' :  
    179.                         luStr[(*luStrNow)++]='\'; luStr[(*luStrNow)++]='v';  
    180.                         break;  
    181.                     default:  
    182.                         luStr[(*luStrNow)++]=pStr[j];  
    183.                 }  
    184.             }  
    185.             luStr[(*luStrNow)++]='"'; luStr[*luStrNow]='';  
    186.             break;  
    187.         case luDynData_lu :     //lu对象  
    188.             if(luStrMax-(*luStrNow)<5)  
    189.             {  
    190.                 kkk--; return 3;    //缓冲区太小  
    191.             }  
    192.             wcscat_s(luStr,luStrMax,L"lu{ ");  
    193.             *luStrNow=*luStrNow+5;  
    194.             j=lu2str(plu->Lu+i,luStr,luStrMax,luStrNow);  //递归调用  
    195.             if(j)  
    196.             {  
    197.                 kkk--; return j;    //错误  
    198.             }  
    199.             if(luStr[*luStrNow-1]==' ')  
    200.             {  
    201.                 if(luStrMax-(*luStrNow)<kkk*4+3)  
    202.                 {  
    203.                     kkk--; return 3;    //缓冲区太小  
    204.                 }  
    205.                 for(j=0;j<kkk*4;j++) luStr[(*luStrNow)++]=' ';  
    206.             }  
    207.             luStr[(*luStrNow)++]='}'; luStr[*luStrNow]='';  
    208.             break;  
    209.         default :  
    210.             j=sprintf_s(str32,32,"%I64d",plu->Lu[i].x);  
    211.             if(j<0)  
    212.             {  
    213.                 kkk--; return 4;    //数据转换错误  
    214.             }  
    215.             if(luStrMax-(*luStrNow)<j+20)  
    216.             {  
    217.                 kkk--; return 3;    //缓冲区太小  
    218.             }  
    219.             wcscat_s(luStr,luStrMax,L""不可识别对象 ");  
    220.             *luStrNow=*luStrNow+8;  
    221.             for(j=0;str32[j];j++) luStr[(*luStrNow)++]=str32[j];  
    222.             luStr[(*luStrNow)++]='"'; luStr[*luStrNow]='';  
    223.         }  
    224.         if(luStrMax-(*luStrNow)<10)  
    225.         {  
    226.             kkk--; return 3;    //缓冲区太小  
    227.         }  
    228.         if(i+1!=plu->Len)  
    229.         {  
    230.             if(plu->Lu[i].BType==luStaData_struniint) bBlank = 0;  
    231.             if(i)  
    232.             {  
    233.                 if(plu->Lu[i-1].BType==luStaData_struniint) bBlank = 1;  
    234.             }  
    235.             if(bBlank)  
    236.             {  
    237.                 wcscat_s(luStr,luStrMax,L",  ");  
    238.                 *luStrNow=*luStrNow+4;  
    239.             }  
    240.             else  
    241.             {  
    242.                 wcscat_s(luStr,luStrMax,L" : ");  
    243.                 *luStrNow=*luStrNow+3;  
    244.             }  
    245.         }  
    246.         else  
    247.         {  
    248.             if(bKeyLu==1)  
    249.             {  
    250.                 wcscat_s(luStr,luStrMax,L" ");  
    251.                 *luStrNow=*luStrNow+2;  
    252.             }  
    253.         }  
    254.     }  
    255.   
    256.     kkk--;  
    257.     if(kkk==0)  
    258.     {  
    259.         pmainlu=NULL;  
    260.         wcscat_s(luStr,luStrMax,L"} ");  
    261.         *luStrNow=*luStrNow+3;  
    262.     }  
    263.     return 0;  
    264. }  
    265. //获得lu对象成员的值,通过pme返回  
    266. //luMember存放以#开头的成员列表,0表示结束  
    267. int getlumember(LuData *pVal,luVOID *luMember,LuData **pme)  
    268. {  
    269.     luLu *plu;  //lu对象指针  
    270.     luVOID i,j,k;  
    271.   
    272.     for(i=0;luMember[i];i++)  
    273.     {  
    274.         if(pVal->BType!=luDynData_lu) return 1;  //无效的lu对象  
    275.         //验证lu对象是否有效  
    276.         plu=(luLu *)SearchKey((char *)&(pVal->x), sizeof(luVOID), luDynData_lu);  
    277.         if(NULL==plu) return 1; //无效的lu对象指针  
    278.         for(j=0;j<plu->Len;j++)  
    279.         {  
    280.             if(plu->Lu[j].BType==luStaData_struniint)  
    281.             {  
    282.                 if((luVOID)plu->Lu[j].x==luMember[i])  
    283.                 {  
    284.                     k=j+1;  
    285.                     if(k<plu->Len)  
    286.                     {  
    287.                         pVal=plu->Lu+k;  
    288.                         break;  
    289.                     }  
    290.                 }  
    291.             }  
    292.         }  
    293.         if(j==plu->Len) return 2;    //没有找到对象成员  
    294.     }  
    295.     *pme=pVal;  
    296.     return 0;  
    297. }  
    298. //设置lu对象成员的值  
    299. //luMember存放以#开头的成员列表,0表示结束;如果从luMember找到的成员是一个lu对象,一般index表示该lu对象成员的序号;index的意义取决于mode。  
    300. //mode表示工作模式。  
    301. //mode=0表示删除对象成员(键 : 值)。index、key_me和me被忽略。  
    302. //mode=1时,index=0表示用新的键值(键key_me : 值me)更新对象成员键值;index<0表示在对象成员前插入键值;index>0表示在对象成员后插入键值。  
    303. //mode=2表示直接用me更新对象成员的值。index和key_me被忽略。  
    304. //mode=3,从luMember找到的成员应是一个lu对象,更新该lu对象第index个成员。key_me被忽略。  
    305. //mode=4,从luMember找到的成员应是一个lu对象,从该lu对象第index个成员前插入me,若index<0或者大于原lu对象长度,从末尾插入me。key_me被忽略。  
    306. int setlumember(LuData *pVal,luVOID *luMember,int index,luVOID key_me,LuData *me,int mode)  
    307. {  
    308.     luLu *plu,*plup;    //lu对象指针  
    309.     LuData *old;  
    310.     int kk;  
    311.     luVOID i,j,k;  
    312.   
    313.     if(mode==0 || mode==1)  //删除、更新、插入键值(键 : 值)  
    314.     {  
    315.         old=NULL;  
    316.         for(i=0;luMember[i];i++)  
    317.         {  
    318.             if(pVal->BType!=luDynData_lu) return 1;  //无效的lu对象  
    319.             //验证lu对象是否有效  
    320.             plu=(luLu *)SearchKey((char *)&(pVal->x), sizeof(luVOID), luDynData_lu);  
    321.             if(NULL==plu) return 1; //无效的lu对象指针  
    322.             for(j=0;j<plu->Len;j++)  
    323.             {  
    324.                 if(plu->Lu[j].BType==luStaData_struniint)  
    325.                 {  
    326.                     if((luVOID)plu->Lu[j].x==luMember[i])  
    327.                     {  
    328.                         k=j+1;  
    329.                         if(k<plu->Len)  
    330.                         {  
    331.                             old=pVal; pVal=plu->Lu+k;  
    332.                             break;  
    333.                         }  
    334.                     }  
    335.                 }  
    336.             }  
    337.             if(j==plu->Len) return 2;    //没有找到对象成员  
    338.         }  
    339.         if(!old) return 2;  //没有找到对象成员  
    340.         if(mode==0)  
    341.         {  
    342.             plup=(luLu *)NewSysObj(luDynData_lu,plu->Len-2,0);  
    343.             if(!plup) return 3; //内存错误  
    344.             for(i=0;i<j;i++) plup->Lu[i]=plu->Lu[i];  
    345.             for(j=i+2;i<plup->Len;i++,j++) plup->Lu[i]=plu->Lu[j];  
    346.             *(luVOID *)&(old->x)=(luVOID)plup;   //更新lu对象  
    347.             DeleteKey((char *)&plu,sizeof(luVOID),luDynData_lu,NULL,1); //销毁以前的lu对象  
    348.             return 0;  
    349.         }  
    350.         if(index==0)  
    351.         {  
    352.             plu->Lu[j].x=key_me; *pVal=*me; return 0;  
    353.         }  
    354.         plup=(luLu *)NewSysObj(luDynData_lu,plu->Len+2,0);  
    355.         if(!plup) return 3; //内存错误  
    356.         index = (index<0) ? j : k+1;  
    357.         for(i=0;i<index;i++) plup->Lu[i]=plu->Lu[i];  
    358.         j=i; plup->Lu[i].BType=luStaData_struniint; plup->Lu[i].VType=luStaData_struniint; plup->Lu[i++].x=key_me; plup->Lu[i++]=*me;  
    359.         for(;i<plup->Len;i++,j++) plup->Lu[i]=plu->Lu[j];  
    360.         *(luVOID *)&(old->x)=(luVOID)plup;   //更新lu对象  
    361.         DeleteKey((char *)&plu,sizeof(luVOID),luDynData_lu,NULL,1); //销毁以前的lu对象  
    362.         return 0;  
    363.     }  
    364.     kk=getlumember(pVal,luMember,&old);  
    365.     if(kk) return kk;  
    366.     if(mode==2)         //直接更新键值  
    367.     {  
    368.         *old=*me; return 0;  
    369.     }  
    370.     if(old->BType!=luDynData_lu) return 1;   //无效的lu对象  
    371.     //验证lu对象是否有效  
    372.     plu=(luLu *)SearchKey((char *)&(old->x), sizeof(luVOID), luDynData_lu);  
    373.     if(NULL==plu) return 1; //无效的lu对象指针  
    374.     if(mode==3)     //更新键值的成员  
    375.     {  
    376.         if(index<0 || index>=plu->Len) return 2;   //没有找到对象成员  
    377.         plu->Lu[index]=*me; return 0;  
    378.     }  
    379.     else if(mode==4)    //插入键值的成员  
    380.     {  
    381.         plup=(luLu *)NewSysObj(luDynData_lu,plu->Len+1,0);  
    382.         if(!plup) return 3; //内存错误  
    383.         if(index<0 || index>plu->Len) index=plu->Len;  
    384.         for(i=0;i<index;i++) plup->Lu[i]=plu->Lu[i];  
    385.         j=i; plup->Lu[i++]=*me;  
    386.         for(;i<plup->Len;i++,j++) plup->Lu[i]=plu->Lu[j];  
    387.         *(luVOID *)&(old->x)=(luVOID)plup;   //更新lu对象  
    388.         DeleteKey((char *)&plu,sizeof(luVOID),luDynData_lu,NULL,1); //销毁以前的lu对象  
    389.         return 0;  
    390.     }  
    391.     else  
    392.     {  
    393.         return 4;   //不正确的工作模式  
    394.     }  
    395. }  
    396.   
    397. void main(void)  
    398. {  
    399.     void *hFor;     //表达式句柄  
    400.     luINT nPara;        //存放表达式的自变量个数  
    401.     LuData *pPara;      //存放输入自变量的数组指针  
    402.     luINT ErrBegin,ErrEnd;  //表达式编译出错的初始位置和结束位置  
    403.     int ErrCode;        //错误代码  
    404.     LuData Val;     //Lu基本数据类型  
    405.     wchar_t luStr[1000];    //保存由lu对象转换来的字符串表达式  
    406.     int luStrNow;       //接收luStr中的字符个数  
    407.     luString *pString;      //Lu动态字符串指针  
    408.     wchar_t ForStr[]=L"(:static)= global(true), static=lu{"--- 使用字符串进行注释 ---" , #生产部 : lu{ #staff : lu{ #王刚 : lu{ #age : 21, #性别 : "男", #工作量 : lu{ 11, 15}, #e_mail : "wanggang@sina.com"}, #李军 : lu{ #age : 25, #性别 : "男", #工作量 : lu{ 17,1.2,1.8}, #website : "http://www.lijun.net/"}}}}";  
    409.   
    410.     //由字符串获得一个唯一的整数  
    411.     luVOID ui_PD;       //#生产部  
    412.     luVOID ui_staff;        //#staff  
    413.     luVOID ui_wanggang; //#王刚  
    414.     luVOID ui_lijun;        //#李军  
    415.     luVOID ui_age;      //#age  
    416.     luVOID ui_gender;       //#性别  
    417.     luVOID ui_workload; //#工作量  
    418.     luVOID ui_e_mail;       //#e_mail  
    419.     luVOID ui_website;      //#website  
    420.     luVOID ui_addr;     //#家庭地址  
    421.     luVOID luMember[10];    //用以查找替换lu对象成员  
    422.     LuData *pme;        //Lu基本数据类型指针,用来返回lu对象  
    423.     LuData me;      //Lu基本数据类型,用来更新lu对象键值  
    424.   
    425.     setlocale(LC_ALL, "chs");   //设置可以输出中文  
    426.   
    427.     if(!InitLu()) return;   //初始化Lu  
    428.   
    429.     ui_PD       =   StrToUniInt((char *)L"生产部",6);  //由字符串获得一个唯一的整数,下同  
    430.     ui_staff        =   StrToUniInt((char *)L"staff",10);  
    431.     ui_wanggang =   StrToUniInt((char *)L"王刚",4);  
    432.     ui_lijun        =   StrToUniInt((char *)L"李军",4);  
    433.     ui_age      =   StrToUniInt((char *)L"age",6);  
    434.     ui_gender       =   StrToUniInt((char *)L"性别",4);  
    435.     ui_workload =   StrToUniInt((char *)L"工作量",6);  
    436.     ui_e_mail       =   StrToUniInt((char *)L"e_mail",12);  
    437.     ui_website  =   StrToUniInt((char *)L"website",14);  
    438.     ui_addr     =   StrToUniInt((char *)L"家庭地址",8);  
    439.   
    440.     ErrCode=LuCom(ForStr,0,0,0,&hFor,&nPara,&pPara,&ErrBegin,&ErrEnd);  //编译表达式  
    441.     if(ErrCode)  
    442.     {  
    443.         printf("表达式有错误!错误代码: %d  ",ErrCode);  
    444.     }  
    445.     else  
    446.     {  
    447.         Val=LuCal(hFor,pPara);  //计算表达式的值  
    448.         if(Val.BType==luDynData_lu)  
    449.         {  
    450.             if(0==lu2str(&Val,luStr,1000,&luStrNow))    //输出lu对象的值  
    451.             {  
    452.                 wprintf(L"%s",luStr);  
    453.             }  
    454.   
    455.             //luMember中存放键的位置“#生产部 : #staff : #王刚 : #age”  
    456.             luMember[0]=ui_PD; luMember[1]=ui_staff; luMember[2]=ui_wanggang; luMember[3]=ui_age;  luMember[4]=0;  
    457.             if(0==getlumember(&Val,luMember,&pme))  
    458.             {  
    459.                 wprintf(L" 查找到 #生产部 : #staff : #王刚 : #age : %I64d ",pme->x);  
    460.             }  
    461.   
    462.             //luMember中存放键的位置“#生产部 : #staff : #李军 : #工作量”  
    463.             luMember[0]=ui_PD; luMember[1]=ui_staff; luMember[2]=ui_lijun; luMember[3]=ui_workload;  luMember[4]=0;  
    464.             pString=(luString *)NewSysObj(luDynData_string,80,0);  
    465.             if(pString) wcscpy_s(pString->Str,80,L"XX省XX市XX区XX路100号大院60#7楼 邮政编码:123456");  
    466.             me.BType=luDynData_string; me.VType=luDynData_string; me.x=0; *(luVOID *)&(me.x)=(luVOID)pString;  
    467.             setlumember(&Val,luMember,-1,ui_addr,&me,1);    //在李军工作量前面增加家庭地址  
    468.   
    469.             //luMember中存放键的位置“#生产部 : #staff : #李军 : #工作量”  
    470.             luMember[0]=ui_PD; luMember[1]=ui_staff; luMember[2]=ui_lijun; luMember[3]=ui_workload;  luMember[4]=0;  
    471.             me.BType=luStaData_double; me.VType=luStaData_double; *(double *)&(me.x)=12.3;  
    472.             setlumember(&Val,luMember,-1,0,&me,4);  //李军的工作量增加12.3,添加到末尾  
    473.   
    474.             if(0==lu2str(&Val,luStr,1000,&luStrNow))    //输出lu对象的值  
    475.             {  
    476.                 wprintf(L"%s",luStr);  
    477.             }  
    478.         }  
    479.     }  
    480.     FreeLu();       //释放Lu  
    481. }  


    运行结果:

    [cpp] view plaincopy
    1. (:static)= global(true), static=  
    2. lu{  
    3.     "--- 使用字符串进行注释 ---",  
    4.     #生产部 : lu{  
    5.         #staff : lu{  
    6.             #王刚 : lu{  
    7.                 #age : 21,  
    8.                 #性别 : "男",  
    9.                 #工作量 : lu{11, 15},  
    10.                 #e_mail : "wanggang@sina.com"  
    11.             },  
    12.             #李军 : lu{  
    13.                 #age : 25,  
    14.                 #性别 : "男",  
    15.                 #工作量 : lu{17, 1.200000, 1.800000},  
    16.                 #website : "http://www.lijun.net/"  
    17.             }  
    18.         }  
    19.     }  
    20. }  
    21.   
    22. 查找到 #生产部 : #staff : #王刚 : #age : 21  
    23.   
    24. (:static)= global(true), static=  
    25. lu{  
    26.     "--- 使用字符串进行注释 ---",  
    27.     #生产部 : lu{  
    28.         #staff : lu{  
    29.             #王刚 : lu{  
    30.                 #age : 21,  
    31.                 #性别 : "男",  
    32.                 #工作量 : lu{11, 15},  
    33.                 #e_mail : "wanggang@sina.com"  
    34.             },  
    35.             #李军 : lu{  
    36.                 #age : 25,  
    37.                 #性别 : "男",  
    38.                 #家庭地址 : "XX省XX市XX区XX路100号大院60#7楼 邮政编码:123456",  
    39.                 #工作量 : lu{17, 1.200000, 1.800000, 12.300000},  
    40.                 #website : "http://www.lijun.net/"  
    41.             }  
    42.         }  
    43.     }  
    44. }  


    4 函数说明

        本例用到了Lu的10个输出函数:初始化Lu的函数InitLu,释放Lu的函数FreeLu,编译表达式的函数LuCom、计算表达式的函数LuCal、申请系统内置动态对象函数NewSysObj、查找键值函数SearchKey、 删除键值函数DeleteKey、由字符串获得一个唯一的整数StrToUniInt、由一个唯一的整数获得字符串UniIntToStr、获得字符串函数GetStr、。从这里查看这些函数的说明:Lu编程指南

    5 难点分析

        代码中提供了3个实用的函数lu2str、getlumember、setlumember以更方便地操作lu对象。

    lu2str:输出lu对象到一个字符串,该字符串用LuCom编译后运行,可重新得到该lu对象。

    getlumember:获得lu对象成员的值。输入参数是类似“键1 : 键2 : 键3 : 0”的整数数组,每一个键是由字符串(Lu脚本中,键以#开头)获得的一个唯一的整数(用StrToUniInt转换)。

    setlumember: 设置lu对象成员的值。可对lu对象的键值进行重置、插入、删除等操作。

        程序主要操作步骤如下:

        (1)对返回lu对象(包含了配置信息)的字符串表达式ForStr进行编译运行;

        (2)用函数lu2str将lu对象转换为字符串表达式并输出;

        (3)从lu对象中查询键“#生产部 : #staff : #王刚 : #age”并输出结果;

        (4)在lu对象中“#生产部 : #staff : #李军 : #工作量”位置前插入键(#家庭地址 : "XX省XX市XX区XX路100号大院60#7楼 邮政编码:123456");

        (5)在lu对象中“#生产部 : #staff : #李军 : #工作量”位置添加键成员(即将lu{17, 1.2, 1.8}修改为lu{17, 1.2, 1.8, 12.3});

        (6)用函数lu2str将lu对象转换为字符串表达式并输出。

    6 其他

        你可能注意到了,我的联系方式就在下面,如有不明之处或有什么建议,可随时与我进行联系。

  • 相关阅读:
    SQL学习_WHERE 数据过滤
    SQL学习_SELECT
    读书笔记之_Win10 与Jmeter5.1.1界面兼容:
    appium+python搭建自动化测试框架_TestAPP框架(三)
    appium+python搭建自动化测试框架_Tools安装(一)
    总目录
    解决IntelliJ IDEA卡顿的方法
    SQL Server
    OBDC无法创建sql server连接
    常见问题
  • 原文地址:https://www.cnblogs.com/haichun/p/3519255.html
Copyright © 2020-2023  润新知