DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: hxh57738897
今日帖子: 27
在线用户: 8
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/10/31 1:53:18
标题:
UniCode 长度有问题 浏览:1598
加入我的收藏
楼主: ShowMessage(IntToStr(Length('言𧨟誩譶𧭛𧮦')));

运行为 9,
但应该为 6.
----------------------------------------------
-
作者:
男 nevergrief (孤独骑士) ★☆☆☆☆ -
盒子活跃会员
2019/10/31 5:20:57
1楼: 应该没问题。第二,第五,第六个字符,应该不在Unicode(也就是Delphi使用的UTF16)的表示范围内。
请使用EditPlus建立一个空文档,存为UTF-16文件。然后你把第二个字符复制到EditPlus里,会发现占了2个字符,即多了一个空格,删掉这个空格,前面这个字马上变方块。这说明EditPlus也不认为它只是一个字符。

假设你不删除它,保存为UTF-16小端格式的文件,然后用UltraEdit打开它,采用16进制观察,果然占了4个Bytes,即5E D8 5B DF,也就是2个字符。

出现这个问题的原因,我认为是中文过于霸道,把一大堆不常见的字符塞到UNICODE里去(常用汉字其实只有2500个),整个UTF-16约有一半的空间都是中文字符(世界上有几百种语言呢!)。但还是有些生僻中文字塞不下怎么办?再在某个特殊的区间再搞附加表,就变成了4个字节表示一个字了(注意,此时在名义上还是UTF-16编码)。具体这个区间是哪个区间,我周末再查一下,然后上来回复。

我甚至有点同情ISO委员会,被中国人逼到快走投无路的地步才会出此下策。
----------------------------------------------
只有偏执狂才能生存!
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/10/31 5:54:25
2楼: Label/Edit/Memo 能看到 '言𧨟誩譶𧭛𧮦',
(RichEdit 不能看到 '言𧨟誩譶𧭛𧮦',这也是一个问题 ??)
黏贴到 Notepad.exe 也正常,
用 Back 键删除,确实是 6 个字,
所以是 UniCode 中文字没错.

Delphi 号称支持 UniCode,
对 2 Bytes 中文能识别为 1 个中文字,
但 
对 4 Bytes 中文却不能识别为 1 个中文字,
令人不解 ?

这样用 For 就无法让 I 得到正确的数.
本来应该 For I=6 , 但却得到 I=9 错误.
----------------------------------------------
-
作者:
男 hardnut (麦轲数据管家) ★☆☆☆☆ -
普通会员
2019/10/31 7:49:20
3楼: 𧭛 U+27B5B 在UTF16下使用代理对才能表示
----------------------------------------------
UniKeeper V10.40 -- 您最贴心的个人数据管理助手
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/10/31 7:49:54
3楼: procedure TForm1.BitBtn1Click(Sender: TObject);
Var I:Integer;
    S:String;
begin
  S:='言𧨟誩譶𧭛𧮦';
  Memo1.Lines.Add(S);
  Memo1.Lines.Add('');
  for i := 1 to Length(S) do
    Memo1.Lines.Add(IntToStr(I)+' '+S[i]);
end;

得到错误的中文

Memo 能正常显示,
但若显示"单一中文字"会出错.
此帖子包含附件:
PNG 图像
大小:21.0K
----------------------------------------------
-
作者:
男 hardnut (麦轲数据管家) ★☆☆☆☆ -
普通会员
2019/10/31 7:53:10
4楼: System.Length 可能不支持代理对
----------------------------------------------
UniKeeper V10.40 -- 您最贴心的个人数据管理助手
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/10/31 9:24:26
5楼: 请使用 UCS4 字符串格式。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 hsj (hsj) ★☆☆☆☆ -
盒子活跃会员
2019/10/31 9:36:11
6楼: var us:UCS4String;
  s:string;
begin
    s:='言𧨟誩譶𧭛𧮦';
    us:=WideStringToUCS4String(s);
    caption:=IntToStr(high(us));
----------------------------------------------
qq:171833017,靖源软件http://www.dxmylove.com
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/11/1 4:40:20
7楼: 试了 2 种方法都不行:

 For I := 1 To High(US) Do
   Memo1.Lines.Add(IntToStr(I)+' '+(US[I]))


 For I := 1 To High(US) Do
   Memo1.Lines.Add(IntToStr(I)+' '+UCS4StringToWideString(US[I]));

另外:
http://www.cppfans.com/cbknowledge/reference/strings/
UCS4String  UCS4/UTF-32 编码的字符串,"没有提供一般的运算功能",仅用于编码转换

http://www.cppfans.com/cbknowledge/reference/strings/ucs4string.asp
UCS4String - 用来储存 UCS4 / UTF-32 编码的字符串
typedef DynamicArray<UCS4Char> UCS4String;
这是 UCS4Char 类型的动态数组,不是字符串类型,
UCS4String 只能用在存储和编码转换,"不能做其他的字符串处理",
C++ Builder 通常的字符串处理需要用 UnicodeString 类型的字符串。
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/11/1 10:07:19
8楼: 大家都白说了半天……
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 lfxsq (lfxsq) ★☆☆☆☆ -
普通会员
2019/11/1 10:14:55
9楼: UTF16中,汉字大多数都占两个字节,但还有部分生僻字占四个字节;
delphi号称使用了UTF16,但对UTF16的支持是不完整的、是简化的,Delphi的UTF16认为所有的字符都占两个字节,没有4个字节的字符,这就造成了楼主代码所出现的问题。
----------------------------------------------
-
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/11/1 10:19:46
10楼: 不知是否有解决方式 ?
若没有,
我打算放弃这个问题,
因为,
这些字很少出现.
----------------------------------------------
-
作者:
男 yayongm (昵  称) ★☆☆☆☆ -
盒子活跃会员
2019/11/1 11:33:09
11楼: 又学到了新知识!!!真·坑!
----------------------------------------------
弱小和无知不是生存的障碍,傲慢才是!
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/11/1 11:35:51
12楼: 支持 6楼 和 8楼。眼瞎的人可能看不见。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 snakegao (snakegao) ★☆☆☆☆ -
盒子活跃会员
2019/11/1 13:48:59
13楼: 羡慕老猫功底
此帖子包含附件:
JPEG 图像
大小:16.6K
----------------------------------------------
-
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/11/1 14:02:49
14楼: 长度  6 在 7F 已解决,
要把"每个中文字"秀在 Memo 上,如 3F
----------------------------------------------
-
作者:
男 hsj (hsj) ★☆☆☆☆ -
盒子活跃会员
2019/11/1 17:35:11
15楼: 我就是根据5楼的提示写的例子,已经能得到了呀,怎么还在盖?
----------------------------------------------
qq:171833017,靖源软件http://www.dxmylove.com
作者:
男 hsj (hsj) ★☆☆☆☆ -
盒子活跃会员
2019/11/1 17:35:56
16楼: 我那是2010写的
----------------------------------------------
qq:171833017,靖源软件http://www.dxmylove.com
作者:
男 msfm (清洁工) ★☆☆☆☆ -
盒子活跃会员
2019/11/1 18:43:28
17楼: 你们说的都不对  delph xe 使用unicode编码使用2个字节表示一个字符 包括中文 遇到生僻的汉字或者其他古怪文字用4个字节 length 这个函数 按照2个字节 算1 

所以造成了 9

caption:=inttostr( sizeof('言'))+' '+inttostr( sizeof('𧨟'))+' '+inttostr( sizeof('誩'))
    +' '+inttostr( sizeof('譶'))+' '+inttostr( sizeof('𧭛'))+' '+inttostr( sizeof('𧮦'));
   2 4 2 2 4 4   == 9
----------------------------------------------
-
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/11/2 2:29:17
18楼: To:hsj
1.根据你的例子我在 7F 就已解决,我也觉的奇怪.
2.我也是使用 Delphi 2010.

To:其它大牛
我不是专业程序师,因为学校学 Pascal,所以我使用 Delphi,
写些自用的工具程序,非工作用,所以没大牛专业水平.

现在:
虽然已解决长度问题,但仍无法把"每个中文字"秀在 Memo 上,如 3F,
若有大牛愿指导解决此问题,万分感谢,
若无大牛愿指导解决此问题,我就放弃解决此问题,
因为写些自用的工具程序,非工作用.

PS:盒子有 Bug ? 為何有 2 個 3F.
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/11/2 9:14:45
19楼: 楼主你如果想要一个一个显示这些4字节的汉字,那么你必须多做一些处理:
注意,以下代码是在Win7+Delphi10.2下测试通过,我的Delphi2010装在XP系统中,而XP系统并不能正确显示这些4字节汉字。
此外,你可以百度一下 "utf16如何区分处理4字节汉字",了解一下UTF16的细节。

procedure TForm1.FormCreate(Sender: TObject);
const
  //代理区首字范围
  SurrogateStart = $D800;
  SurrogateEnd   = $DBFF;
var
  s: string;
  i: Integer;
  w: Word;
begin
  s:='言𧨟誩譶𧭛𧮦';

  Memo1.Text := s;

  i := 1;
  while i <= Length(s) do begin
    w := Ord(s[i]);
    if (w < SurrogateStart) or (w > SurrogateEnd) then begin
      Memo1.Lines.Add(s[i]);
    end else begin
      Memo1.Lines.Add(Copy(s, i, 2));
      Inc(i);
    end;
    Inc(i);
  end;

end;
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/11/2 9:18:21
20楼: 示例图片:
此帖子包含附件:
PNG 图像
大小:9.6K
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 limin (limin) ★☆☆☆☆ -
盒子活跃会员
2019/11/2 11:00:06
21楼: 学习了
----------------------------------------------
-
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/11/3 4:10:26
22楼: To:iamdream

非常感谢 大牛 的指导.

编程 : Windows 7 X64 + Delphi 2010.
运行 :
Windows XP X86(VMWare) 测试通过.
Windows 7 X64(Real PC) 测试通过.

To:其它 大牛
基于本人编程自用的水平,无法达到 大牛 水平,垦请见谅.
Pascal : 学校教.
Delphi : 毕业后,自学.

低水平总结,有错请指导:

2F
Delphi RichEdit 不支持 4 Bytes UniCode 中文.

7F
Delphi UCS4String 只能用在存储和编码转换,"不能做其他的字符字串处理".
此帖子包含附件:
PNG 图像
大小:42.0K
----------------------------------------------
-
作者:
男 plusv (plusv) ★☆☆☆☆ -
普通会员
2019/11/3 4:11:23
23楼: 补图:

对照组:

Memo1 : 错
Memo2 : 对
RichEdit1 : 错
RichEdit2 : 对
此帖子包含附件:
PNG 图像
大小:56.1K
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行140.625毫秒 RSS