【问题标题】:Getting char value in Delphi 7在 Delphi 7 中获取 char 值
【发布时间】:2013-12-03 09:43:32
【问题描述】:

我正在 Delphi 7 中制作一个程序,该程序应该将 unicode 字符串编码为 html 实体字符串。 例如,“ABCģķī”将导致“ABCģķī

现在有两个基本的东西:

  1. Delphi 7 不是 Unicode,所以我不能直接在代码中编写 unicode 字符来对其进行编码。
  2. 代码页由 255 个条目组成,每个条目包含一个特定于该代码页的字符,前 127 个除外,对于所有代码页都是相同的。

那么 - 如何获得 1-255 范围内的字符值?

我尝试了Ord(Integer),但它也返回超过 255 的值。基本上,一切都很好(A 返回 65 以此类推),直到我的字符串达到非拉丁 unicode。

还有其他返回char值的方法吗?任何帮助表示赞赏

【问题讨论】:

  • 在 Delphi 7 中,ord(c) 其中c 的类型为char,在0..255 范围内。很明显,您拥有char 以外的其他东西。你有什么?有代码吗?
  • 您要编码的字符来自哪里,它们是什么格式?正如大卫所提到的,如果您将缺少正确转换的代码作为讨论的起点发布,那将非常有帮助。
  • 您需要 WideCharWideString 类型。将 Word 大小的值类型转换为 WideChar,反之亦然。
  • @FreeConsulting 鉴于 ord(somechar) 可以返回 >255 的值,我们似乎已经有了 WideChar,但猜测并不好玩
  • 午休刚回来 :) @DavidHeffernan 我使用WideString 作为输入,从WideCharString 获取值作为输出。 @Heina WideString 用于转换来自文件。

标签: delphi unicode delphi-7 html-entities html-encode


【解决方案1】:

我建议您避免使用像瘟疫这样的代码页。

我会考虑两种 Unicode 方法:WideString 和 UTF-8.

Widestrings 的优势在于它是 Windows 的“原生”,如果您需要使用 Windows API 调用,这会有所帮助。缺点是存储空间,并且它们(如 UTF-8)可能需要多个 WideChar 来编码完整的 Unicode 空间。

UTF-8 is generally preferable。与 WideStrings 一样,这是一种多字节编码,因此特定的 unicode“代码点”可能需要字符串中的多个字节来对其进行编码。如果您对字符串进行大量逐个字符的处理,这只是一个问题。

@DavidHeffernan cmets (correctly) WideStrings 可能在某些情况下更紧凑。但是,只有当您绝对确定您的编码文本会真正更紧凑(不要忘记标记!)时,我才会推荐 UTF-16,而且这种紧凑性对您来说非常重要。

【讨论】:

  • 这里有一些错误信息。对于某些文本,UTF-16 比 UTF-8 更紧凑。例如,我想到了中文。你的说法是不正确的,WideString 没有涵盖完整的 Unicode 空间。 WideString 类型包装了 COM BSTR,它使用 UTF-16 编码,这是 Unicode 的完整编码。它是一种可变长度编码,就像 UTF-8 一样。
  • @DavidHeffernan 我不会处理中文 :) 事实上,我的程序应该能够编码到/从 2 个代码页 - 1257 和 1251(波罗的海和西里尔文)。
  • @Roddy Compactness 没有发挥任何重要作用。 (只要能用就行)
  • @user3060709 那么,哪种 ANSI 编码同时支持这两个代码页?你为什么还要考虑ANSI?你对 Unicode 有什么看法?
【解决方案2】:

在 HTML 4 中,数字字符引用与 HTML 使用的字符集相关。该字符集是通过<meta> 标记在HTML 本身中指定的,还是通过HTTP/MIME Content-Type 标头或其他方式在带外指定的,都没有关系。因此,"ABCģķī" 将是 "ABCģķī" 的准确表示,仅当 HTML 使用 UTF-16 时。如果 HTML 使用 UTF-8,则正确的表示将是 "ABCģķī""ABCģķī"。大多数其他字符集不支持那些特定的 Unicode 字符。

在 HTML 5 中,数字字符引用包含原始 Unicode 代码点值,而与 HTML 使用的字符集无关。因此,"ABCģķī" 将表示为 "ABC#291;ķī""ABCģķī"

因此,要回答您的问题,您要做的第一件事是决定是否需要对数字字符引用使用 HTML 4 或 HTML 5 语义。然后,您需要将 Unicode 数据分配给使用 UTF-16 的 WideString(这是 Delphi 7 原生支持的唯一 Unicode 字符串类型),然后:

  1. 如果您需要 HTML 4:

    A.如果 HTML 字符集不是 UTF-16,则使用 WideCharToMultiByte()(或等效项)将 WideString 转换为该字符集,然后循环输出未保留字符的结果值和保留值的字符引用,使用 @ 987654333@ 用于十进制表示法或IntToHex() 用于十六进制表示法。

    B.如果 HTML 字符集是 UTF-16,则只需循环遍历 WideString 中的每个 WideChar,按原样输出未保留字符和保留值的字符引用,使用 IntToStr() 十进制表示法或 IntToHex() 十六进制表示法.

  2. 如果您需要 HTML 5:

    A.如果WideString 不包含任何代理对,则只需循环遍历WideString 中的每个WideChar,按原样输出未保留字符和保留值的字符引用,使用IntToStr() 十进制表示法或IntToHex()用于十六进制表示法。

    B.否则,使用WideStringToUCS4String()WideString 转换为UTF-32,然后循环输出未保留代码点的结果值和保留代码点的字符引用,使用IntToStr() 十进制表示法或IntToHex() 十六进制表示法。

【讨论】:

    【解决方案3】:

    如果我正确理解了 OP,我将把它留在这里。

    function Entitties(const S: WideString): string;
    var
      I: Integer;
    begin
      Result := '';
      for I := 1 to Length(S) do
      begin
        if Word(S[I]) > Word(High(AnsiChar)) then
          Result := Result + '#' + IntToStr(Word(S[I])) + ';'
        else
          Result := Result + S[I];
      end;
    end;
    

    【讨论】:

    • 在制作函数标题 =P 时,您的思绪似乎在别处
    • 这适用于 UCS2,但不适用于 UTF-16。它不识别代理对。
    猜你喜欢
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 2012-09-14
    • 1970-01-01
    相关资源
    最近更新 更多