AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Char-Array mal "einfach"

Ein Thema von himitsu · begonnen am 26. Feb 2009
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#1

Char-Array mal "einfach"

  Alt 26. Feb 2009, 17:18
OK, wie einige bemerkt haben, geht es ja nicht immer so leicht seinen Array's etwas zuzuweisen...

Delphi-Quellcode:
var MyArray: Array[1..32] of Char;

// dieses geht ja meistens noch
MyArray := 'ne Konstante';

// aber hier zickt der Kompiler schon mal rum
MyArray := S; // S is ein String
so, da kommt nun ein kleiner Record ins Spiel,
welcher das Array enthält und noch ein paar Operatoren verpaßt bekommt.

PS: TWideString ist 'ne Variable von mir ... hab die entweder als UnicodeString oder WideString definiert (je nach Delphi)

Auch hatte ich mir ein paar Operatoren gesparrt ... also in dieser Variante geht nur Folgendes:
(den Rest kann man sich aber leicht nachrüsten ... hatte halt für mein Projekt so ausgereicht)
Delphi-Quellcode:
Var MyArrayRecord: TWideString32;
  S: String {or AnsiString, WideString od UnicodeString};

MyArrayRecord := 'constant';
MyArrayRecord := S;
S := MyArrayRecord;
If MyArrayRecord = 'abcdethen ...;
If MyArrayRecord <> 'abcdethen ...;
Delphi-Quellcode:
Type TWideString32 = packed Record
    Data: Array[1..32] of WideChar;
    Class Operator Implicit(Const Value: AnsiString): TWideString32;
    Class Operator Implicit(Const Value: TWideString): TWideString32;
    Class Operator Implicit(Const Value: TWideString32): TWideString;
    Class Operator Equal (Const A: TWideString32; Const B: TWideString): Boolean;
    Class Operator NotEqual(Const A: TWideString32; Const B: TWideString): Boolean;
  End;

Class Operator TWideString32.Implicit(Const Value: AnsiString): TWideString32;
  Var S: TWideString;

  Begin
    S := TWideString(Value);
    If Length(S) > Length(Result.Data) Then System.Error(reRangeError);
    Move(PWideChar(S)^, Result.Data, Length(S) * 2);
    If Length(S) < Length(Result.Data) Then
      FillChar(Result.Data[Length(S) + 1], (Length(Result.Data) - Length(S)) * 2, 0);
  End;

Class Operator TWideString32.Implicit(Const Value: TWideString): TWideString32;
  Begin
    If Length(Value) > Length(Result.Data) Then System.Error(reRangeError);
    Move(PWideChar(Value)^, Result.Data, Length(Value) * 2);
    If Length(Value) < Length(Result.Data) Then
      FillChar(Result.Data[Length(Value) + 1], (Length(Result.Data) - Length(Value)) * 2, 0);
  End;

Class Operator TWideString32.Implicit(Const Value: TWideString32): TWideString;
  Var i: Integer;

  Begin
    i := 0;
    While (i < Length(Value.Data)) and (Value.Data[i + Low(Value.Data)] <> #0) do Inc(i);
    SetLength(Result, i);
    Move(Value.Data, PWideChar(Result)^, i * 2);
  End;

Class Operator TWideString32.Equal(Const A: TWideString32; Const B: TWideString): Boolean;
  Var S: TWideString;

  Begin
    S := A;
    Result := S = B;
  End;

Class Operator TWideString32.NotEqual(Const A: TWideString32; Const B: TWideString): Boolean;
  Begin
    Result := not (A = B);
  End;
hier noch 'ne kleine Ansi-Variante
Delphi-Quellcode:
Type TAnsiString32 = packed Record
    Data: Array[1..32] of AnsiChar;
    Class Operator Implicit(Const Value: AnsiString): TAnsiString32;
    Class Operator Implicit(Const Value: TAnsiString32): AnsiString;
    Class Operator Equal (Const A: TAnsiString32; Const B: AnsiString): Boolean;
    Class Operator NotEqual(Const A: TAnsiString32; Const B: AnsiString): Boolean;
  End;

Class Operator TAnsiString32.Implicit(Const Value: AnsiString): TAnsiString32;
  Begin
    If Length(Value) > Length(Result.Data) Then System.Error(reRangeError);
    Move(PAnsiChar(Value)^, Result.Data, Length(Value));
    If Length(Value) < Length(Result.Data) Then
      FillChar(Result.Data[Length(Value) + 1], (Length(Result.Data) - Length(Value)), 0);
  End;

Class Operator TAnsiString32.Implicit(Const Value: TAnsiString32): AnsiString;
  Var i: Integer;

  Begin
    i := 0;
    While (i < Length(Value.Data)) and (Value.Data[i + Low(Value.Data)] <> #0) do Inc(i);
    SetLength(Result, i);
    Move(Value.Data, PAnsiChar(Result)^, i);
  End;

Class Operator TAnsiString32.Equal(Const A: TAnsiString32; Const B: AnsiString): Boolean;
  Var S: AnsiString;

  Begin
    S := A;
    Result := S = B;
  End;

Class Operator TAnsiString32.NotEqual(Const A: TAnsiString32; Const B: AnsiString): Boolean;
  Begin
    Result := not (A = B);
  End;
hatte auch mal versucht 'nen Template zusammenzubasteln, aber muß da wohl noch etwas lernen ...
Delphi-Quellcode:
<?xml version="1.0" encoding="utf-8" ?>
<codetemplate   xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
            version="1.0.0">
   <template name="TWideStringX" invoke="manual">
      <description>
        WideChar-Array
      </description>
      <author>
        himitsu
      </author>
      <point name="size">
         <text>
            32
         </text>
         <hint>
            Größe des Arrays
         </hint>
      </point>
      <point name="name">
         <script language="Delphi">
            InvokeCodeCompletion;
         </script>
         <text>
            TWideString32
         </text>
         <hint>
            Name des Records
         </hint>
      </point>
      <code language="Delphi" context="typedecl" delimiter="|"><![CDATA[   Type |name| = packed Record
         Data: Array[1..|size|] of WideChar;
         Class Operator Implicit(Const Value: AnsiString): |name|;
         Class Operator Implicit(Const Value: WideString): |name|;
         Class Operator Implicit(Const Value: |name|): WideString;
         Class Operator Equal (Const A: |name|; Const B: WideString): Boolean;
         Class Operator NotEqual(Const A: |name|; Const B: WideString): Boolean;
      End;]]>
      </code>
      <code language="Delphi" context="decl" delimiter="|"><![CDATA[   Class Operator |name|.Implicit(Const Value: AnsiString): |name|;
      Var S: WideString;

      Begin
         S := WideString(Value);
         If Length(S) > Length(Result.Data) Then System.Error(reRangeError);
         Move(PWideChar(S)^, Result.Data, Length(S) * 2);
         If Length(S) < Length(Result.Data) Then
            FillChar(Result.Data[Length(S) + 1], (Length(Result.Data) - Length(S)) * 2, 0);
      End;

   Class Operator |name|.Implicit(Const Value: WideString): |name|;
      Begin
         If Length(Value) > Length(Result.Data) Then System.Error(reRangeError);
         Move(PWideChar(Value)^, Result.Data, Length(Value) * 2);
         If Length(Value) < Length(Result.Data) Then
            FillChar(Result.Data[Length(Value) + 1], (Length(Result.Data) - Length(Value)) * 2, 0);
      End;

   Class Operator |name|.Implicit(Const Value: |name|): WideString;
      Var i: Integer;

      Begin
         i := 0;
         While (i < Length(Value.Data)) and (Value.Data[i + Low(Value.Data)] <> #0) do Inc(i);
         SetLength(Result, i);
         Move(Value.Data, PWideChar(Result)^, i * 2);
      End;

   Class Operator |name|.Equal(Const A: |name|; Const B: WideString): Boolean;
      Var S: WideString;

      Begin
         S := A;
         Result := S = B;
      End;

   Class Operator |name|.NotEqual(Const A: |name|; Const B: WideString): Boolean;
      Begin
         Result := not (A = B);
      End;]]>
      </code>
   </template>
</codetemplate>
Wie man womöglich am Template sieht, reicht es, wenn man für jede Array-Länge erstmal 'ne eigene Recorddefinition braucht (also sollte man sich auf ein paar gebräuchliche Längen einigen/beschränken).
Dabei muß aber nur in der Definition die Länge und der Typen-Name geändert werden

Für die Ansi-Variante macht sich ein ShortString vermutlich etwas besser (bei maximal 255 Zeichen).

Ansonsten läßt sich dieser Record fast wie ein "normaler" String benutzen, ohne das man sich noch um etwas kümmern muß.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz