注册 登录
编程论坛 VFP论坛

字符串大、小端互换,VFP有没有更优雅的算法?

cssnet 发布于 2022-10-07 10:07, 1123 次点击
我们知道,将字符串在ANSI与Unicode之间相互转换,VFP提供了Strconv()函数,只不过,此函数有个小小的遗憾:
只能转换Unicode LE(小端),无法转换Unicode BE(大端)。
至于什么是“大端、小端”,讲出来有段古,有兴趣的网友不妨百度一下“《格利佛游记》小人国的战争”。

C语言有现成的大、小端转换函数:
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

VFP可能要自己写一个:
*--------------------
function LE2BE(lcString)
* 将传入的字符串,以2个字节为1组,左右反转
#if .f.
    lcANSI = "我是ANSI字符串"
    lcUnicode_LE = strconv(lcANSI, 5)    &&将双字节字符转换为 UNICODE (LE)
    lcUnicode_BE = LE2BE(lcUnicode_LE)    &&将UNICODE (LE)转为UNICODE (BE)
#endif .f.
local lnLen, lcReturn, i
lnLen = int(len(lcString)/2)*2    &&容错处理:确保字符串长度为偶数
lcReturn = ""
for i = 1 to lnLen step 2
    lcReturn = lcReturn + substr(lcString, i+1, 1) + substr(lcString, i, 1)
endfor i
return lcReturn
*--------------------

这函数本质上是以16位整型数表示的Unicode字符,高字节右移8位,低字节左移8位。
C语言可直接用<<和>>,直接将16位整型数的高、低字节,分别左移8位和右移8位即可。
至于VFP,我不太清楚有无类似简洁优雅的整型数方式来处理字符串?
8 回复
#2
laowan0012022-10-07 10:15
这是木瓜大师的myfll里提供的函数,不知是否是你要的
程序代码:
函数名:StrReverse(cString[,isMultipleByte])
缩写:strr
反转一个字符串。支持中文字符串反转。
返回值:
反转后的字符串。
参数:
cString:字符型,要反转的字符串,如:abc,反转后为cba
[,isMultipleByte]:逻辑值,为.T.时,检测中文进行反转,为.F.时,按字节反转,默认值为.F.。
示例代码
Set Library To myFll

?StrReverse("abc123")        &&反转后的结果为 321cba

?StrReverse("汉字测试")        &&由于默认按字节反转,结果为:允獠肿汉

?StrReverse("汉字测试",.T.)    &&结果为:试测字汉


Set Library To

#3
吹水佬2022-10-07 10:16
什么情况下需要去转换
#4
cssnet2022-10-07 10:18
若用C语言写这个转换,真心是非常优雅的——连函数也不必写,只需用1个宏即可:
//2字节大小端转化
#define SWAP_UINT16(x) ((((uint16_t)x) >> 8) | ((((uint16_t)x) << 8)))
//4字节大小端转化
#define SWAP_UINT32(x) ((((uint32_t)x) >> 24) | ((((uint32_t)x) & 0x00FF0000) >> 8) | ((((uint32_t)x) & 0x0000

所以才会有了顶楼的感慨:
VFP有无类似优雅的方法?
#5
cssnet2022-10-07 11:10
以下是引用吹水佬在2022-10-7 10:16:36的发言:
什么情况下需要去转换


Windows系统默认自然是Unicode小端,只不过网络传入的字符参数,难以统一,有时会接收到Unicode大端字符,在VFP中就要首先转换至小端,否则不好进行后续的处理。
#6
吹水佬2022-10-07 12:33
以下是引用cssnet在2022-10-7 10:18:52的发言:

若用C语言写这个转换,真心是非常优雅的——连函数也不必写,只需用1个宏即可:
//2字节大小端转化
#define SWAP_UINT16(x) ((((uint16_t)x) >> 8) | ((((uint16_t)x) << 8)))
//4字节大小端转化
#define SWAP_UINT32(x) ((((uint32_t)x) >> 24) | ((((uint32_t)x) & 0x00FF0000) >> 8) | ((((uint32_t)x) & 0x0000

所以才会有了顶楼的感慨:
VFP有无类似优雅的方法?

传说的一句搞定吧,VFP应该可以直译过来
#7
csyx2022-10-07 17:34
BITLSHIFT()、BITRSHIFT()、BITOR()、BITAND()

[此贴子已经被作者于2022-10-7 17:35编辑过]

#8
吹水佬2022-10-07 17:41
BITxxx..、BINTOC、CTOBIN
#9
cssnet2022-10-07 18:26
4#的C代码是我看错了,那仅仅是2字节或4字节的单个Word或单个Dword转换;若是字符串(字符数组)的话,仍需循环的。
倘若必须循环,则顶楼的VFP代码已是最直观的字节转换了,实无必要再刻意寻求太过刁钻古怪邪门算法。

1