代码之家  ›  专栏  ›  技术社区  ›  jrodenhi

将ansisting转换为unicode字符串

  •  5
  • jrodenhi  · 技术社区  · 15 年前

    我正在将d2006程序转换为d2010。我的数据库中每个字符串都有一个单字节的值,我需要将它加载到一个具有loadfromstream的控件中,所以我的计划是将该字符串写入一个流,并将其与loadfromstream一起使用。但它不起作用。在研究这个问题时,我看到了一个问题,它告诉我,我不真正理解从ansisting到unicode字符串的转换是如何工作的。下面是一段单独的代码,它说明了我所困惑的问题:;

    procedure TForm1.Button1Click(Sender: TObject); {$O-}
    var
      sBuffer: String;
      oStringStream: TStringStream;
      sAnsiString: AnsiString;
      sUnicodeString: String;
      iSize1,
      iSize2: Word;
    begin
      sAnsiString := '12345';
      oStringStream := TStringStream.Create(sBuffer);
      sUnicodeString := sAnsiString;
      iSize1 := StringElementSize(sAnsiString);
      iSize2 := StringElementSize(sUnicodeString);
      oStringStream.WriteString(sUnicodeString);
    end;
    

    如果在最后一行中断,并检查ostringstream的bytes属性,您将看到它如下所示:

    Bytes (49 {$31}, 50 {$32}, 51 {$33}, 52 {$34}, 53 {$35}
    

    我原以为它看起来像

    (49 {$31}, 00 {$00}, 50 {$32}, 00 {$00}, 51 {$33}, 00 {$00}, 
     52 {$34}, 00 {$00}, 53 {$35}, 00 {$00} ...
    

    显然我的期望是错误的。但是,如何将ansisting转换为unicode呢?

    我没有从loadfromstream中得到正确的结果,因为它一次从流中读取两个字节,但是它接收的数据没有按这种方式排列。我应该怎么做才能给loadfromstream一个基于Unicode字符串的格式良好的数据流?

    谢谢你的帮助。

    4 回复  |  直到 6 年前
        1
  •  5
  •   kludg    15 年前

    ostringstream.writeString参数的类型是什么?如果它是ansisting,那么您有一个从unicode到ansi的隐式转换,这解释了您的示例。


    更新:现在真正的问题是tstringstream如何在内部存储数据。 以下代码示例(Delphi 2009)

    procedure TForm1.Button1Click(Sender: TObject);
    var
      S: string;
      SS: TStringStream;
    
    begin
      S:= 'asdfg';
      SS:= TStringStream.Create(S);  // 1 byte per char
      SS.WriteString('321');
      Label1.Caption:= SS.DataString;
      SS.Free;
    end;
    

    tstringstream在内部使用默认的系统ansi编码(每个字符1个字节)。 构造函数和WriteString过程将字符串参数从Unicode转换为ANSI。

    要重写此行为,必须在构造函数中明确声明编码:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      S: string;
      SS: TStringStream;
    
    begin
      S:= 'asdfg';
      SS:= TStringStream.Create(S, TEncoding.Unicode);  // 2 bytes per char
      SS.WriteString('321');
      Label1.Caption:= SS.DataString;
      SS.Free;
    end;
    
        2
  •  0
  •   lkessler    15 年前

    我想你想用:

    LoadFromStream(stream, TEncoding.ASCII);
    

    如果单字节文本不是ASCII,而是基于代码页,那么这可能有效:

    LoadFromStream(stream, TEncoding.GetEncoding(1252));
    

    其中“1252”是单字节文本所基于的代码页。

        3
  •  0
  •   Ken Bourassa    15 年前

    流格式在很大程度上取决于tstringstream.encoding。在示例中,使用的代码页应该与sbuffer相同(请参见tstringstream.create中的implementation)。

    自从 oStringStream.WriteString(sUnicodeStream); 似乎保存为单个字节,我假设sbuffer是一个ansistry或rawbytestring。

    现在。。。为什么阅读失败…您还没有向我们提供一个您如何在该流中读回的示例。

        4
  •  0
  •   Rubén Pozo    6 年前

    在Delphi最新版本中,您可以使用Tencoding:

    TEncoding.UTF8.GetString(TEncoding.ANSI.GetBytes(MyString))