2Pascal-新时代的Pascal

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

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

[复制链接]

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
83968
跳转到指定楼层
楼主
发表于 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

积分
83968
沙发
 楼主| 发表于 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

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

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

使用道具 举报

2

主题

13

帖子

117

积分

注册会员

Rank: 2

积分
117
地板
发表于 2015-6-5 17:15:02 | 只看该作者
京东数码购物支持本站
Delphi String 常用字串符处理函数

来源:http://www.cnblogs.com/onechen/p/4555139.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

2

主题

9

帖子

58

积分

版主

Rank: 7Rank: 7Rank: 7

积分
58
5#
发表于 2015-6-12 09:57:08 | 只看该作者
京东数码购物支持本站
delphi TStringList 用法详解

//TStringList 常用方法与属性 :
var
List: TStringList;
i: Integer;
begin
List := TStringList.Create;
List.Add('Strings1'); {添加}
List.Add('Strings2');
List.Exchange(0,1); {置换}
List.Insert(0,'Strings3'); {插入}
i := List.IndexOf('Strings1'); {第一次出现的位置}
List.Sort; {排序}
List.Sorted := True; {指定排序}
List.Count; {总数}
List.Text; {文本集合}
List.Delete(0); {删除, 0是第一个数据}
List.LoadFromFile('c:/tmp.txt');{打开}
List.SaveToFile('c:/tmp.txt'); {保存}
List.Clear; {清空}
List.Free; {释放}
end;





//读入字符串
var
List: TStringList;
begin
List := TStringList.Create;
List.CommaText := 'aaa,bbb,ccc,ddd';
//相当于: List.Text := 'aaa' + #13#10 + 'bbb' + #13#10' + 'ccc' + '#13#10' + 'ddd';

ShowMessage(IntToStr(List.Count)); //4
ShowMessage(List[0]); //aaa

List.Free;
end;



//置换分隔符
var
List: TStringList;
begin
List := TStringList.Create;
List.Delimiter := '|';
List.DelimitedText := 'aaa|bbb|ccc|ddd';

ShowMessage(IntToStr(List.Count)); //4
ShowMessage(List[0]); //aaa

List.Free;
end;



//类似的哈希表操作法
var
List: TStringList;
begin
List := TStringList.Create;

List.Add('aaa=111');
List.Add('bbb=222');
List.Add('ccc=333');
List.Add('ddd=444');

ShowMessage(List.Names[1]); //bbb
ShowMessage(List.ValueFromIndex[1]); //222
ShowMessage(List.Values['bbb']); //222

//ValueFromIndex 可以赋值:
List.ValueFromIndex[1] := '2';
ShowMessage(List[1]); //bbb=2

//可以通过 Values 赋值:
List.Values['bbb'] := '22';
ShowMessage(List[1]); //bbb=22

List.Free;
end;

//避免重复值
var
List: TStringList;
begin
List := TStringList.Create;

List.Add('aaa');

List.Sorted := True; //需要先指定排序
List.Duplicates := dupIgnore; //如有重复值则放弃

List.Add('aaa');

ShowMessage(List.Text); //aaa

//Duplicates 有3个可选值:
//dupIgnore: 放弃;
//dupAccept: 结束;
//dupError: 提示错误.

List.Free;
end;


//排序与倒排序
{排序函数}
function DescCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := -AnsiCompareText(List[Index1], List[Index2]);
end;

procedure TForm 1.Button1Click(Sender: TObject);
var
List: TStringList;
begin
List := TStringList.Create;

List.Add('bbb');
List.Add('ccc');
List.Add('aaa');

//未排序
ShowMessage(List.Text); //bbb ccc aaa

//排序
List.Sort;
ShowMessage(List.Text); //aaa bbb ccc

//倒排序
List.CustomSort(DescCompareStrings); //调用排序函数
ShowMessage(List.Text); //ccc bbb aaa

//假如:
List.Sorted := True;
List.Add('999');
List.Add('000');
List.Add('zzz');
ShowMessage(List.Text); //000 999 aaa bbb ccc zzz
end;
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
83968
6#
 楼主| 发表于 2015-6-12 12:46:52 | 只看该作者
京东数码购物支持本站
顶楼上,总结的不错。
TStringList 是最好用的工具。
(C)(P)Flying Wang
回复 支持 反对

使用道具 举报

2

主题

13

帖子

117

积分

注册会员

Rank: 2

积分
117
7#
发表于 2015-6-16 08:10:38 | 只看该作者
京东数码购物支持本站
字串处理别忘了还有官方建议的 TStringBuilder

http://docwiki.embarcadero.com/L ... tils.TStringBuilder
回复 支持 反对

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
83968
8#
 楼主| 发表于 2015-6-16 09:00:08 | 只看该作者
京东数码购物支持本站
还有更难懂的
TMarshal

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

使用道具 举报

90

主题

293

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
83968
9#
 楼主| 发表于 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

积分
83968
10#
 楼主| 发表于 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
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 23:39 , Processed in 0.084945 second(s), 24 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

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