广告位联系
返回顶部
分享到

CAPL脚本对.ini配置文件的高阶操作

相关技巧 来源:互联网 作者:酷站 发布时间:2022-05-27 23:50:35 人浏览
摘要

前言 ????前面其实我们已经掌握了对配置文件,文本文件的读写函数和方法,如果一个INI文件只有少许的键值对,那么用内置函数也还凑合,但是当INI文件中的键值对多了起来,内置函

前言

????前面其实我们已经掌握了对配置文件,文本文件的读写函数和方法,如果一个INI文件只有少许的键值对,那么用内置函数也还凑合,但是当INI文件中的键值对多了起来,内置函数一个一个去读写的方式就非常繁琐,本节就针对这种情况对INI文件的读写方式进行升级,以达到快速便捷读写多键值对的情况????
演示软硬件环境 Win10 x64 ; CANoe 11 SP2 x64

批量读取代码讲解

1?? 本节演示仍然基于 bmw2.cfg ,新增一个Nework Node ,用于按键触发测试

2?? 下图的test.ini 文件是我们的测试文件,键值对有很多

3?? 我们按照编程习惯,控制语句放在IniAuto.can文件中,函数和全局变量放在IniAuto.cin文件中IniAuto.can中代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

/*@!Encoding:936*/

includes

{

  #include "IniAuto.cin"

}

 

on key 'u'

{

  write("*****press u***********");

  getKeyValueFromINI(Ini_data_path,var_Ini_Data);

  if(1) //debug check values

  {

    int i ;

    write ("************************Debug data******************************");

    for(i = 0 ;i < var_Ini_Data.items ;i++)

    {

      write ("*******section:%s*******",var_Ini_Data.section[i]);

      write ("*******index:%d***keys:%s*******",i,var_Ini_Data.keys[i]);

      write ("*******index:%d***values:%s*******",i,var_Ini_Data.values[i]);

    }  

  }

}

4?? 头文件 IniAuto.cin中代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

/*@!Encoding:936*/

 

variables

    char Ini_data_path[100] = ".//TestModule//IniAutoCode//test.ini"; 

    char Ini_data_path_out[100] = ".//TestModule//IniAutoCode//test_out.ini"; 

    const int max_items = 200 ;

    const int max_keys_size = 50 ;

    const int max_values_size = 300 ;

   

    struct Ini_Data // record Ini data

  {

    int  items;

    char section[max_items][max_keys_size];

    char keys   [max_items][max_keys_size];

    char values [max_items][max_values_size];

  

  };

   struct Ini_Data var_Ini_Data;

}

 

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

批量读INI

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

int getKeyValueFromINI(char FilePath[], struct Ini_Data Temp_var_Ini_Data)

{

  int i,j,glbHandle;

  char buffer[max_values_size];

  long section_find, key_find;

  char section_temp[max_keys_size];

  char keys_temp_1[max_keys_size]    ,keys_temp_2[max_keys_size];

  char values_temp_1[max_values_size],values_temp_2[max_values_size];

   

  glbHandle = OpenFileRead (FilePath,0);

   

  if (glbHandle!=0 )

  {  

    write("Open file :%s passed.",FilePath);

    j = 0;

     

    while(fileGetStringSZ(buffer,elcount(buffer),glbHandle)!=0)  

    {    

      section_find = strstr_regex(buffer, "\\[.*?\\]"); //用正则表达式匹配 []

      if(section_find != -1)

       {

        ClearCharArray(section_temp);

        substr_cpy (section_temp,buffer,1,strlen(buffer)-2,  elcount(buffer));//掐头去尾,去掉[]

        continue ;

       }

       

      key_find = strstr(buffer, "=");    

       

      if(key_find != -1)

      {

        ClearCharArray(keys_temp_1);ClearCharArray(keys_temp_2); //临时字符串使用之前要初始化

        substr_cpy (keys_temp_1,buffer,0,key_find,  elcount(buffer));// = 前的key

        remove_space(keys_temp_1,keys_temp_2);                 //清除字符传中的空格

        

        ClearCharArray(values_temp_1);ClearCharArray(values_temp_2);

        substr_cpy (values_temp_1,buffer,key_find+1,strlen(buffer) - key_find, elcount(buffer));//= 后的value

        remove_space(values_temp_1,values_temp_2);

 

        strncpy (Temp_var_Ini_Data.section[j],section_temp  ,elcount(Temp_var_Ini_Data.section[j]));

        strncpy (Temp_var_Ini_Data.keys[j]   ,keys_temp_2   ,elcount(Temp_var_Ini_Data.keys[j]));

        strncpy (Temp_var_Ini_Data.values[j] ,values_temp_2 ,elcount(Temp_var_Ini_Data.values[j]));

        j++;  // index ++  

      }          

    } 

    Temp_var_Ini_Data.items = j ;  // 最后统计多少行数据

    fileClose (glbHandle); 

  } 

  else

  {

    write("Read file :%s failed.",FilePath);

    return 0; //failed   

  }

  return 1; //passed

}

 

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

去除字符串的空格

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

void remove_space(char input_c[],char out_c[])

{

   

  int i,j ;

  j=0;

   

  for(i = 0; i< strlen(input_c);i++)

  {

    if (input_c[i] != ' ')

    {

      out_c[j] = input_c[i];

      j++;

    }

  }

}

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

字符串初始化

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

void ClearCharArray(char arrIn[])

{

    int i, length;

  length = strlen(arrIn);

  for(i=length;i>=0;i--){

   arrIn[i]=0x00;

  }

}

5?? 头文件 IniAuto.cin中不良定义解释
说明:因为涉及到批量操作,所有都化整为零,全部key/value的数据类型都视为字符串操作,实际代码中,如果有整形浮点型的,请再进行格式转换

6?? 头文件 IniAuto.cin中 getKeyValueFromINI 函数的注释

7?? 按键’u‘,看下测试结果:

我们已经把ini的键值对都转换为了CAPl的数组类型,那么这样我们在下一步无论怎么去批量读,改写,删除

批量写入代码讲解

  • 1?? 我们读取了之后,可能的操作是改写,删除,添加,甚至是新建操作,那么这一系列操作之后,我们还要保存到原来的INI文件的。
  • 2?? 我们按照编程习惯,控制语句放在IniAuto.can文件中,函数和全局变量放在IniAuto.cin文件中

IniAuto.can中的增加的代码:

1

2

3

4

5

6

7

/*@!Encoding:936*/

on key 'm'

{

  write("*****press m***********");

   

  SetKeyValueToINI(Ini_data_path_out,var_Ini_Data);

}

3?? 头文件 IniAuto.cin中增加的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

/*@!Encoding:936*/

 

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

批量写入Key/value 到INI

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

int SetKeyValueToINI(char FilePath[], struct Ini_Data Temp_var_Ini_Data)

{

  long retVal;

  int i,j,glbHandle;

  char buffer[max_values_size];

  char section_temp[max_items][max_keys_size];

  char tempText[max_values_size];

 

   

  ClearCharArray(section_temp);

  glbHandle = OpenFileWrite(FilePath,0); // 写入文件,以覆盖源文件的形式

   

  if (glbHandle!=0 )

  {  

    write("Open file :%s passed.",FilePath);

    j = 0 ;

    for(i=0;i< Temp_var_Ini_Data.items ; i++)

    {

                   

      if((strncmp(Temp_var_Ini_Data.section[i],"",strlen(Temp_var_Ini_Data.section[i])) !=0)&&

         (strncmp(Temp_var_Ini_Data.keys[i],   "",strlen(Temp_var_Ini_Data.keys[i]))    !=0)) //section、key 值不为空,写入

         

      {

        /* section_temp是一个临时字符串数组,用来存储已经写过的section,

        每次执行写入前会先检查下是否已经写过了,如果没写过,就添加到这个素组中,如果在这个数组中找到了,就不再写入Ini了

        */

        retVal = SeachValueInArrary(Temp_var_Ini_Data.section[i],section_temp );

         

        if (retVal== -1)

        {      

          snprintf(tempText, elcount(tempText), "\n[%s]\n", Temp_var_Ini_Data.section[i]);

          filePutString (tempText, elcount(tempText),glbHandle);      

          strncpy (section_temp[j],Temp_var_Ini_Data.section[i]  ,elcount(section_temp[j]));

          j++ ;

        }

 

        snprintf(tempText, elcount(tempText), "%s = %s\n", Temp_var_Ini_Data.keys[i],Temp_var_Ini_Data.values[i]); //写入键值对

        filePutString (tempText, elcount(tempText),glbHandle);

      }

    }     

       

    fileClose (glbHandle); 

  } 

  else

  {

    write("Write file :%s failed.",FilePath);

    return 0; //failed   

  }

  return 1; //passed

}

 

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

在一个中查找指定值

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

long SeachValueInArrary(char target[] ,char source[][])

{

   

  int i ;

   

  for(i= 0;i<elcount(source);i++)

  {

    if(strncmp(target,source[i],strlen(target)) ==0 )

    {

      //write("Seached value %s in the arrary and the index is %d",target,i);

      return i;

    }

  }

  return -1 ;

}

4?? 我们再在按键’u‘,读取了INI文件后,什么操都不要做,然会按下’m‘,看下测试结果已经都写进来了

更新INI文件键值对

  • 1?? 我们读取了之后,可能的操作是改写其中的某个键值对,
  • 2?? 我们按照编程习惯,控制语句放在IniAuto.can文件中,函数和全局变量放在IniAuto.cin文件中

IniAuto.can中的增加的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

on key 'i' //改写key

{

 

  write("*****press %c***********",this);

  updateINIvalue(0,"Tester ","Runer","",var_Ini_Data,Ini_data_path_out); // 改写第一个键值对的key,索引值是0,把Tester改成Runer

   

}

 

on key 'p' //改写value

{

 

  write("*****press %c***********",this);

  updateINIvalue(0,"Tester","Tester","https://blog.csdn.net/qq_34414530",var_Ini_Data,Ini_data_path_out); // 改写第一个键值对的value,索引值是0,

   

}

 

on key 'k' //改写value

{

 

  write("*****press %c***********",this);

  updateINIvalue(0,"Tester","Runer","https://blog.csdn.net/qq_34414530",var_Ini_Data,Ini_data_path_out); // 对key和value同时操做

   

}

3?? 头文件 IniAuto.cin中增加的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

更改键值对,不完善,异常捕捉代码需完善

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

 

void updateINIvalue(long index ,char section[],char keys[],char values[],struct Ini_Data Temp_var_Ini_Data,char FilePath[])

{    

  if(index < Temp_var_Ini_Data.items)

  {

    if(strncmp(section,"",strlen(section)) !=0)// 不等于空,就写入

    {

      strncpy (Temp_var_Ini_Data.section[index],section  ,elcount(Temp_var_Ini_Data.section[index]));

    }

    if(strncmp(keys,"",strlen(keys)) !=0)// 不等于空,就写入

    {

      strncpy (Temp_var_Ini_Data.keys[index]   ,keys     ,elcount(Temp_var_Ini_Data.keys[index]));

    }

    if(strncmp(values,"",strlen(values)) !=0)// 不等于空,就写入

    {

      strncpy (Temp_var_Ini_Data.values[index] ,values   ,elcount(Temp_var_Ini_Data.values[index]));

    }

         

     SetKeyValueToINI(FilePath, Temp_var_Ini_Data); //保存

  }

  else

  {

    write("index out of range.");

  }

}

4?? 我们看下测试结果

???? 先按键’u‘读取原始INI,然会按下’i‘,改写Key值:

???? 先按键’u‘读取原始INI,然会按下p,改写value值:

???? 先按键’u‘读取原始INI,然会按下k,改写key/value值:

删除INI文件键值对

  • 1?? 我们读取了之后,可能的操作是改写其中的删除某个键值对,
  • 2?? 我们按照编程习惯,控制语句放在IniAuto.can文件中,函数和全局变量放在IniAuto.cin文件中

IniAuto.can中的增加的代码:

1

2

3

4

5

6

on key 'h' //删除键值对

{

 

  write("*****press %c***********",this);

  deleteINIItem(3,var_Ini_Data,Ini_data_path_out); // 删除Peed = 20.5

}

3?? 头文件 IniAuto.cin中增加的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

删除键值对,这里根据索引去删除,也可以再重载函数根据key值或者value值去删除

当然也可以重载函数,传入索引数组,去批量删除,

后期有时间再继续完善

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

 

void deleteINIItem(long index ,struct Ini_Data Temp_var_Ini_Data,char FilePath[])

{    

  if(index < Temp_var_Ini_Data.items)

  {

    strncpy (Temp_var_Ini_Data.section[index],""  ,elcount(Temp_var_Ini_Data.section[index])); 

    strncpy (Temp_var_Ini_Data.keys[index]   ,""  ,elcount(Temp_var_Ini_Data.keys[index]));

    strncpy (Temp_var_Ini_Data.values[index] ,""  ,elcount(Temp_var_Ini_Data.values[index]));

         

    SetKeyValueToINI(FilePath, Temp_var_Ini_Data); //保存

  }

  else

  {

    write("index out of range.");

  }

}

4?? 我们看下测试结果

???? 先按键’u‘读取原始INI,然会按下’h‘,删除Peed = 20.5:

增加INI文件键值对

  • 1?? 我们读取了之后,可能的操作是增加某个键值对
  • 2?? 我们按照编程习惯,控制语句放在IniAuto.can文件中,函数和全局变量放在IniAuto.cin文件中

IniAuto.can中的增加的代码:

1

2

3

4

5

6

7

8

9

10

11

12

on key 'j' //增加键值对

{

 

  write("*****press %c***********",this);

  appendINIItem("Number","place","shanghai",var_Ini_Data,Ini_data_path_out); // 在[Number] 下增加一个place = shanghai,

}

 

on key 'g' //增加键值对,新的section

{

  write("*****press %c***********",this);

  appendINIItem("Position","place","shanghai",var_Ini_Data,Ini_data_path_out); // 在[Number] 下增加一个place = shanghai,

}

3?? 头文件 IniAuto.cin中增加的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

/***************************************************************************************************

----------------------------------------------------------------------------------------------------

Revision history:

Date   2022-2-18

Author mayixiaobing

增加键值对,下面的代码支持加入新的section,如果要在已有的section

----------------------------------------------------------------------------------------------------

***************************************************************************************************/

 

void appendINIItem(char section[],char keys[],char values[],struct Ini_Data Temp_var_Ini_Data,char FilePath[])

{   

  long retIndex ;

  long items;

  long i ;

                     

  if((strncmp(section,"",strlen(section)) !=0)&&

     (strncmp(keys   ,"",strlen(keys))    !=0)) //section、key 值不为空,写入     

  {

       

    items = Temp_var_Ini_Data.items ; 

     

    retIndex = SeachValueInArrary(section,Temp_var_Ini_Data.section);   

       

    if (retIndex == -1)//如果是新的section,直接尾处追加

    {           

      strncpy (Temp_var_Ini_Data.section[items],section  ,elcount(Temp_var_Ini_Data.section[items]));

      strncpy (Temp_var_Ini_Data.keys[items]   ,keys     ,elcount(Temp_var_Ini_Data.keys[items]));

      strncpy (Temp_var_Ini_Data.values[items] ,values   ,elcount(Temp_var_Ini_Data.values[items])); 

 

    }

    else //如果是已有section,从索引处,向后顺移

    {

      for(i= items;i > retIndex ;i--)

      {

        strncpy (Temp_var_Ini_Data.section[i],Temp_var_Ini_Data.section[i-1]  ,elcount(Temp_var_Ini_Data.section[i]));

        strncpy (Temp_var_Ini_Data.keys[i]   ,Temp_var_Ini_Data.keys[i-1]     ,elcount(Temp_var_Ini_Data.keys[i]));

        strncpy (Temp_var_Ini_Data.values[i] ,Temp_var_Ini_Data.values[i-1]   ,elcount(Temp_var_Ini_Data.values[i]));      

      }

      strncpy (Temp_var_Ini_Data.section[retIndex],section  ,elcount(Temp_var_Ini_Data.section[retIndex]));

      strncpy (Temp_var_Ini_Data.keys[retIndex]   ,keys     ,elcount(Temp_var_Ini_Data.keys[retIndex]));

      strncpy (Temp_var_Ini_Data.values[retIndex] ,values   ,elcount(Temp_var_Ini_Data.values[retIndex])); 

    }

     

             

    Temp_var_Ini_Data.items = items + 1;   

    SetKeyValueToINI(FilePath, Temp_var_Ini_Data); //保存

  }

}

4?? 我们看下测试结果

???? 先按键’u‘读取原始INI,然会按下’j‘,在已有的section新加一个key/value:

???? 先按键’u‘读取原始INI,然会按下’g‘,新建section以及key/value:

新建INI文件

1?? 我们也可以直接新建一个键值对文件,不需要提前读取

2?? 我们按照编程习惯,控制语句放在IniAuto.can文件中,函数和全局变量放在IniAuto.cin文件中

IniAuto.can中的增加的代码,下面是新增两个参数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

on key 'f' //新建ini文件

{

 

  write("*****press %c***********",this);

  var_Ini_Data.items = 2;

  strncpy (var_Ini_Data.section[0],"test"  ,elcount(var_Ini_Data.section[0]));

  strncpy (var_Ini_Data.keys[0]   ,"para1" ,elcount(var_Ini_Data.keys[0]));

  strncpy (var_Ini_Data.values[0] ,"1234"  ,elcount(var_Ini_Data.values[0]));

   

  strncpy (var_Ini_Data.section[1],"test"  ,elcount(var_Ini_Data.section[0]));

  strncpy (var_Ini_Data.keys[1]   ,"para2" ,elcount(var_Ini_Data.keys[0]));

  strncpy (var_Ini_Data.values[1] ,"4567"  ,elcount(var_Ini_Data.values[0]));

   

  SetKeyValueToINI(Ini_data_path_out,var_Ini_Data);

}

3?? 头文件IniAuto.cin中增加的代码:

1

无新增.cin代码

4?? 我们看下测试结果


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 : https://blog.csdn.net/qq_34414530/article/details/124996877
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计