2Pascal-新时代的Pascal

 找回密码
 立即注册
搜索
热搜: fastreport
查看: 5073|回复: 18
打印 上一主题 下一主题

字符串 编码 和 跨平台 讨论 01

[复制链接]

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
跳转到指定楼层
楼主
发表于 2015-6-4 17:10:11 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
京东购书支持本站
var
  str: string;
begin
  str[Low(str) + 从 0 开始的编号]  //保证跨平台。
end;

str.xxx 函数 从 0 开始。例如  str.IndexOf()
xxx(str) 这种函数,如果是 以前就有的 从 1 开始。例如 Pos(str)


有关 DLL 字符串 的 建议 看看 第 9 楼 和 第 17 楼。
当然,其他楼也要看看。
(C)(P)Flying Wang
回复

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
沙发
 楼主| 发表于 2015-6-4 17:11:17 | 显示全部楼层
京东数码购物支持本站
移动平台下
没有 Char WideChar AnsiChar PChar PWideChar PAnsiChar  了。只有 Byte TBytes 。
建议用  TEncoding.XXXX 来处理和 string 的转换。
例如

str := TEncoding.UTF8.GetString(你的Bytes);

AnsiBytes := TEncoding.ANSI.GetBytes(str);


关键是 使用 TEncoding TBytes PByte string 这几种类型 综合使用。
即可跨平台了。

当然, TNetEncoding 里头也有一些 函数是支持  Tbytes 的。
例如
TNetEncoding.Base64.DecodeStringToBytes(sKey+'=');
也有反过来的版本
接收用的TBytes := TNetEncoding.Base64.Encode(TBytes变量);


在任何情况下,都禁止用 XXXXToYYYY、UTF8Encode 和 UTF8Decode 这些旧的函数。因为全都不如 TEncodiing.编码.函数 这种准确。
使用 TEcnding 的时候,一定要指定编码,否则跨平台会效果不一致。


D7 的 string 默认是 Ansistring ,同时你可以强迫他成为 Utf8String。

高版本的 string 是 UnicodeString,为了安全起见,不要去想他是什么编码,你应该当成无编码的。中性的。(这是重点)
需要编码的时候,就该 TBytes 出场了。
用 TEncoding 来完成 string 和 Tbytes 的 转换即可。
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
板凳
 楼主| 发表于 2015-6-4 17:17:31 | 显示全部楼层
京东购书支持本站
MarshaledAString 和 TBytes 可以互相强制转换。
但是 MarshaledAString 一般是以 #0 结尾的。当然也可能不是。
但是 TBytes 是个数组,所以是有大小的。有时候,内容很大,有效内容却不大。

所以,尽量不要乱转换。
确定他们的大小再说。
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
地板
 楼主| 发表于 2015-6-12 12:46:52 | 显示全部楼层
京东数码购物支持本站
顶楼上,总结的不错。
TStringList 是最好用的工具。
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
5#
 楼主| 发表于 2015-6-16 09:00:08 | 显示全部楼层
京东数码购物支持本站
还有更难懂的
TMarshal

TMarshaller
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
6#
 楼主| 发表于 2015-7-2 09:25:02 | 显示全部楼层
京东数码购物支持本站
TMarshaller.AsRaw 可以返回 MarshaledAString,但是编码不确定。
如果你确保对方需要的是 UTF8 编码的字符串,可以使用 AsUtf8().ToPointer 来返回 MarshaledAString,MarshaledAString(TMarshaller.Asutf8(你的字符串).ToPointer);
如果对方需要的是 UTF8 的,也可以 MarshaledAString(Utf8Encode(你的字符串)); 来返回。
如果你需要的是 PANSICHAR 的。可以使用
AsAnsi().ToPointer 来返回。

下面是用 TMarshaller 的写法。

var
  M : TMarshaller;
  A: PAnsiChar;
  U: PUTF8Char;
  MAA: MarshaledAString;
  MAU: MarshaledAString;
begin
  A := M.AsAnsi('你的字符串' ).ToPointer;
  U := M.AsUtf8('你的字符串' ).ToPointer;
  MAA := MarshaledAString(TMarshaller.AsAnsi('你的字符串' ).ToPointer);
  MAU := MarshaledAString(TMarshaller.AsUtf8('你的字符串' ).ToPointer);
end;


下面是用 TEncoding 的写法。
var
  A: PAnsiChar;
  W: PWideChar;
  U: PUTF8Char;
begin
  A := Addr(TEncoding.ANSI.GetBytes('你的字符串' + #0)[0]);
  W := Addr(TEncoding.Unicode.GetBytes('你的字符串' + #0)[0]);
  U := Addr(TEncoding.UTF8.GetBytes('你的字符串' + #0)[0]);
end;
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
7#
 楼主| 发表于 2015-7-24 13:41:49 | 显示全部楼层
京东数码购物支持本站
delphi 2010升级到xe8后,decodestring汉字出现:No mapping for the
http://www.2pascal.com/forum.php ... =1692&fromuid=4
(出处: 2Pascal-新时代的Pascal)


大家可以看看这个问题的解决。
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
8#
 楼主| 发表于 2015-8-5 18:30:06 | 显示全部楼层
京东数码购物支持本站
[迁安]Nightmourn(328783896)  18:29:51
@[北京]老猫 Android转换gb2312 urlencode要怎么百度…

[北京]老猫(1765535979)  18:30:45
@[迁安]Nightmourn 此问题在中文 DELPHI 开发界(对于你们这些不懂得自己研究的人来说)尚属首次 研究,百度没有收录。

答案就是 使用 TNetEncdong.Url.Encode(TBytes 版本的参数); (很早之前,我们自己研究出的答案)

如何获取 TBytes 的结果,前面已经讨论过了。

(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
9#
 楼主| 发表于 2015-8-6 18:40:41 | 显示全部楼层
京东数码购物支持本站
楼上的问题,太过低级,前面的讨论 综合一下,就是答案。
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81994
10#
 楼主| 发表于 2015-8-7 09:31:41 | 显示全部楼层
京东数码购物支持本站
  Input: TBytes;

  SetLength(Output, SM4_BLOCKSIZE);
  FillChar(Input[0], SM4_BLOCKSIZE, 0);

不能 FillChar(Input,

会发生非法操作。
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|新时代Pascal论坛

GMT+8, 2024-5-16 21:46 , Processed in 0.078755 second(s), 24 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表