苏州网站建设制作设计,南昌seo锐创,微网站如何做微信支付宝支付宝,百度seo不正当竞争秒收摘要#xff1a;这是一篇写给新手的关于CODESYS开发环境的小白教程#xff0c;一看就懂...... 在以前的《CODESYS开发教程7-字符串及其基本操作》教程中#xff0c;介绍了字符串及其基本操作#xff0c;有朋友看了以后觉得不过瘾#xff0c;希望有一些关于字符串的更加深入…摘要这是一篇写给新手的关于CODESYS开发环境的小白教程一看就懂...... 在以前的《CODESYS开发教程7-字符串及其基本操作》教程中介绍了字符串及其基本操作有朋友看了以后觉得不过瘾希望有一些关于字符串的更加深入的介绍。今天的教程重点给大家讲解一下长字符串操作的库及相关函数还有长字符串长度255处理相关的一些骚操作比如自己写的字符串长度函数、字符串中查找字符的函数等。 一、关于STRING类型的说明
CODESYS的STRING字符串类型有几点重要的规则需要给大家介绍一下。
1.字符串存储
字符串实际上是一个字符数组。比如定义一个字符串并赋值。
str : STRING:’CODESYS’;
str实际上是一个长度为7的字符数组可以使用数组的方式来访问。也就是说可以通过str[0]来获得字符串的首字符’C’。在实际存储中字符是采用ASCII码的形式来保存的。在判断str[0]是否为字符C时需要跟字符C的ASCII码来进行比较即str[0]16#43 或 str[0]67 会输出TRUE。但是使用str[0]‘C’则会报编译错误。
在CODESYS中没有字符变量但是可以用BYTE来定义字符比如16#4A为字母J。
2.字符串大小
在定义字符串类型的变量时如果不指定字符串的长度字符串变量允许的最多字符数为80。
str : STRING:’CODESYS’; //此时str实际为最大长度80个字符的数组str[0..79]
字符串变量实际需要的内存为字符串的长度加一个字节即上面定义的str变量所占存储空间为81个字节SIZEOF(str)81。
3.长字符串
CODESYS环境没有限制字符串变量类型的长度因此长度超过255的字符串也是合法的C语言的字符串最大长度为255。例如可以定义个长度为1000字节的字符串
str1 : STRING(1000);
需要注意的是在《字符串及其基本操作》中介绍的字符串处理函数处理的字符数不能超过255即只能对STRING(255)类型的字符串进行操作。长度超过255字符的字符串可以通过数组读取的方式取出来单独处理。
受字符数限制的字符串处理函数主要包括CONCAT、DELETE、FIND、INSERT、LEFT左选、LEN、MID、REPLACE、RIGHT。
测试程序如下
结果如下图所示 如上图中所示 字符串类型变量str1的长度为3所占内存空间大小是81字节。
对于长字符串strLong其实际长度为10000。使用LEN()函数获取的长度为255而使用函数StrLenA()获取的长度为正常的10000所占内存空间大小为10001字节。
4.关于长字符串支持的最长度
测试发现编译器3.5.16支持的长字符串最大尺寸为4294967295即2^32-1。用仿真运行测试了一下我用的这个控制器微秒P4CM发现最多只能支持2147483647即2^31-1超过该长度编译能通过但是下载运行时会报错要么是控制器内存不足要么是底层数据类型的长度限制导致的。
PROGRAM main
VARi : INT;str1 : STRING;strLong : STRING(10000);t0 : INT;t1 : UINT;t2 : INT;t3 : DINT;t4 : UINT;
END_VARstr1:abc;
FOR i:0 TO 9999 DOstrLong[i]:16#3C;
END_FOR
t0:LEN(str1);
t1:SIZEOF(str1);
t2:LEN(strLong);
t3:StrLenA(ADR(strLong));
t4:SIZEOF(strLong);
二、长字符串的处理
长字符串长度255的处理有两种方式一种是使用CODESYS提供的长字符串函数库一种是自己编程处理。
1.使用长字符串函数库StringUtils
对于长度超过255个字符的字符串CODESYS提供了相应的库库名称是StringUtils如下图所示。 主要包含ANSI和Unicode两种类型字符串的处理函数。
理论上可以处理最大长度42949672952^32-1的字符串。 函数功能 CODESYS-ST 备注 长度 StrLenA/StrLenW 仅统计字符数不包含结束符 字符串比较 StrCmpA/StrCmpW、StrCaseCmpA/StrCaseCmpW、StrCaseCmpEndA、StrCaseCmpStartA 带Case的不区分大小写 字符串拷贝 StrCpyA/StrCpyW 中间取位 StrMidA/StrMidW 字符串连接 StrConcatA/StrConcatW 空字符串检查 StrIsNullOrEmptyA/StrIsNullOrEmptyW 删除 StrDeleteA/StrDeleteW 替换 StrReplaceA/StrReplaceW 查找 StrFindA/StrFindW、StrCaseFindA/StrCaseFindW 带Case的不区分大小写 移除空字符 StrTrimA、StrTrimEndA、StrTrimStartA StrPadLeftA/StrPadLeftW、StrPadRightA/StrPadRightW 字符或字符串的大小写转换 StrToLowerA、StrtoUpperA、CharToUpper/WCharToUpper //注意以上函数的字符串类型输入均为POINTER TO BYTE即指向字节的指针。
以下str均为STRING类型变量。
1CharToUpper(ch)
将字符ch转换为大写字符。
示例ch:CharToUpper(s); //结果为S
2StrCmpA(ADR(str1),ADR(str2))、StrCaseCmpA()
比较字符串str1和str2。str1和str2相等时返回0str1小于str2时返回-1str1大于str2时返回1str1或str2为非法字符串如空指针时返回-2。
这里的大于和小于开始我也不明白是什么意思测试了一下发现是根据字符串的ASCII码来区分的。小于意思就是str1的ASCII码值小于str2的ASCII码,即’a’和‘b’比较会返回-1而‘A’和‘a’比较会返回1。而字符串的比较就比较魔幻了不太清楚返回结果的规则是什么例如‘a’和‘ab’比较会返回-1而‘bcd’和‘ab’比较会返回1。对于字符比较还有点用途但是对于字符串比较有何用处实在是没想出来~~☹
注意StrCmpA比较时区分大小写StrCaseCmpA比较时不区分大小写。
示例bFlag:StrCmpA(ADR(str1),ADR(str2));
3StrFindA(ADR(str1),ADR(str2),uiStart)、StrCaseFindA
在字符串str1中查找指定的字符串str2。找到字符串str2会返回字符串的首位置未找到返回0给定空字符串会返回-1。
注意这里的str1和str2最多只能为STRING(255)。
示例str1:’ABCD’; str2:’CD’;
pos:StrFindA(ADR(str1), ADR(str2), 1); //pos3
4StrConcatA(ADR(str1),ADR(str2),iBuffSize)
将字符串str1连接到str2后面通常是将str2加到str1后面。如果iBuffSize大小不够或者给定的字符串为NULL时将不进行连接并返回FALSE。
注意iBuffSize的值必须比大于等于LEN(str1)LEN(str2)1否则字符串连接会失败。
示例str1:’ABCD’; str2:’CD’;
flag:StrFindA(ADR(str1), ADR(str2), 7); //str2’CDABCD’,flagTRUE
flag:StrFindA(ADR(str1), ADR(str2), 7); //str2’CD’,flagFALSE
5StrCpyA(pBuf,iBuffSize,ADR(str))
字符串拷贝即从字符串str中拷贝iBuffSize个字节到缓冲区pBuf。拷贝完成后会返回拷贝的字符数该数据包含结束符’\0’或“\0”。
注意pBuf不能为NULL。另外iBuffSize是包含结束符的个数即12表示实际只能拷贝11个字符。
示例str1:’’; str2:’CDEFG’;
num:StrCpyA(ADR(str1),3,ADR(str2)); //str1’CD’
6StrDeleteA(ADR(str),iLen,iPos)
从字符串str中的iPos开始删除长度为iLen的字符。iPos1为从第一个字符开始。
示例str:’ABCD’
StrDeleteA(ADR(str),2,1); //str’CD’
7StrIsNullOrEmptyA(ADR(str))
判断字符串str是否为NULL或空。
8StrLenA(ADR(str))
获取字符串str长度。该函数是通过寻找字符串中的结束字符’\0’来实现的。如果str为NULL时会返回-1。
9StrMid(ADR(str),iBuffSize,iLen,iPos,ADR(strDest),uiResBufsize)
获取字符串str中从iPos开始长度为iLen的字符。iPos1为从第一个字符开始。
10StrPadLeftA(ch,ADR(str1),ADR(str2),iBuffSize)、StrPadRightA
将字符串str1从左侧开始填充为指定字符ch填充个数iBuffSize-LEN(str1)结果放在字符串str2中并返回TRUE。当iBuffSize小于str1的字符个数时不进行填充并返回FALSE。
示例str1:‘ab’
flag:StrPadLeftA(16#41,ADR(str1),ADR(str2),7); //str2’AAAAAab’
11StrReplaceA(ADR(str),iBuffSize,ADR(str2),iLenIn,iLenToRe,iLenToReWith,iPos)
将字符串中从iPos开始长度为iLen的字符替换为str2。iPos1为从第一个字符开始。
注意这里的str1和str2最多只能为STRING(255)。
示例str1:’ab’; str2:’2’;
StrReplaceA(ADR(str1),7,ADR(str2),2,2,2,1); //str1’2b’
写到这里忍不住吐槽一下CODESYS的帮助文档真的是垃圾中间这几个长度参数根本看不懂是什么意思…☹大家真要用的话自己去测试我实在是受够了~~
12StrToLowerA、StrToUpperA
字符串中字符的大小写转换。
示例str:’abcd’;
StrToUpperA(ADR(str)); //str’ABCD’
13StrTrimA(ADR(str))、StrTrimEndA、StrTrimStartA
移除字符串中的空白字符空白字符指ASCII码为9、10、13、32的字符。
后面两个函数为仅移除结尾或开头的空白字符。
示例str:’ abcd ’;
StrTrimA(ADR(str)); //str’abcd’
对于UNICODE字符串的相关处理函数用法基本类似这里就不一一列举了主要是我懒病犯了~~大家可以自己去看帮助文档。
2.自己编程处理
在第一节里面有介绍STRING类型实际上字符数组操作起来非常方便因此可以自己编写相关的字符串处理函数。废话就不多说了先上示例
1长字符串长度函数FN_LEN
函数功能类似于StrLenA()代码如下 FUNCTION FN_LEN : DINT
VAR_INPUTpstr1 : POINTER TO BYTE;
END_VAR
VARi : DINT;strl : DINT;
END_VAR
strl:0;
i:0;
WHILE (pstr1[i] 16#0) DOi:i1;strl:strl1;
END_WHILE
FN_LEN:strl; 运行结果如下图所示 2长字符串查找函数FN_FIND
函数功能类似于StrFindA()函数代码如下
FUNCTION FN_FIND : DINT
VAR_INPUTpstr1 : POINTER TO BYTE;pstr2 : POINTER TO BYTE;uiStart : UINT;
END_VAR
VARi : DINT;strl : DINT;pos : DINT;iStart : DINT;
END_VAR
pos:0;
IF uiStart0 THENiStart:uiStart;
ELSEiStart:0;
END_IF
strl:StrLenA(pstr1);
FOR i:iStart TO strl-1 DOIF (pstr1[i] 16#0) AND (pstr1[i]pstr2^) THENpos:i1;EXIT;ELSEpos:0;END_IF
END_FOR
FN_FIND:pos;
运行结果如下图所示 例子就写这么多复杂的我也不太会~~懒病是没有救的……。从上面的例子可以看到各种字符串处理函数就是遍历字符串找到特定的字符并进行处理。其实字符串操作基本都是这个套路大家可以根据自己的需要去开发一下功能更加强大的字符串处理函数。 五、总结
对于长度超过255个字符的字符串想偷懒的话就直接用CODESYS提供的StringUtils库如果这个库还不能满足你的要求那当然是自己动手了做到这一步要恭喜你了功力又提升了是不是考虑自己弄个字符串函数库。大家可以看到本文里面对于长字符串的处理都是用指针的方式在传递参数其实在自己写的时候直接用STRING也是可以的但是由于CODESYS的类型检查非常严格字符串类型STRING作为函数参数时STRING和STRING(255)是不同的这就导致实际使用的时候不如指针方便因为指针是没有传递字符串长度的限制问题。好吧这么简单的事实想必大家都是知道的终于发现我是真的很啰嗦~~ ------------------ 原创不易感兴趣的多支持