Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Strin an ShortString zuweisen, wie? (https://www.delphipraxis.net/202464-strin-shortstring-zuweisen-wie.html)

DualCoreCpu 6. Nov 2019 21:36

Strin an ShortString zuweisen, wie?
 
Hallo,

ich habe Variablen vom Typ Shortstring, an die ich nun Variableninhalte vom Typ String zuweisen will. Nun hat ja wohl ein String ein anderes Format (Größe eines Zeichens in Byte), als der ShortString.

Wie kann ich da möglichst unkompliziert einen String an eine Shortstring-Variable zuweisen. Ich brauche hierfür hauptsächlich nur das englische Alphabet, mur für MenuName könnte ich die Deutschen Umlaute noch zusätzlich gebrauchen.

Delphi-Quellcode:
type
**TMenuNameStr = array[0..31] of Ansichar;
**TProgNameStr = array[0..255] of AnsiChar;
**TDirNameStr = array[0..255] of AnsiChar;
**TCfgNameStr = array[0..29] of Ansichar;
**TOptionsStr = array[0..127] of Ansichar;
**TRegisteredCommand = class(TObject)
**private
****FMenuName: TMenuNameStr;
****FProgName: TProgNameStr;
****FDirName: TDirNameStr;
****FOptions: TOptionsStr;
****FCfgFile: TCfgNameStr;
****function GetCfgFile: ShortString;
****function GetDirName: ShortString;
****function GetMenuName: ShortString;
****function GetOptions: ShortString;
****function GetProgName: ShortString;
****procedure SetCfgFile(const Value: ShortString);
****procedure SetDirName(const Value: ShortString);
****procedure SetMenuName(const Value: ShortString);
****procedure SetOptions(const Value: ShortString);
****procedure SetProgName(const Value: ShortString);
**public
***{
* * constructor Create;
* * destructor Destroy; override;
** }
****constructor Create;
****property MenuName: ShortString read GetMenuName write SetMenuName;
****property ProgName: ShortString read GetProgName write SetProgName;
****property DirName: ShortString read GetDirName write SetDirName;
****property Options: ShortString read GetOptions write SetOptions;
****property CfgFile: ShortString read GetCfgFile write SetCfgFile;
**end;

**TCommandsList = class(TObjectList)
****property Command: TRegisteredCommand read GetCommand write SetCommand;
**end;
Wegen säterer Absicht, die Commands in einer Datei abzulegen, habe ich hier Shortstring gewählt. Wenn ich die Kommandos aber nun in einer Ini Datei ablegen will, tritt beim Wieder einlesen das Problem auf, dass ja Inifile.ReadString() einen String, nicht ShortString zurück gibt. Wie kann ich diesen String nun an ShortString zuweisen?

Delphi-Quellcode:

var
 nMenu,nPath,nProg,nConf,nOpts: String;

    nMenu := FIniFile.ReadString('Command','Menuname','');
    nPath := FIniFile.ReadString('Command','Directory','');
    nProg := FIniFile.ReadString('Command','Exename','');
    nConf := FIniFile.ReadString('Command','CfgFile','');
    nOpts := FIniFile.ReadString('Command','Options','');

    move(nMenu[1],FCommand.MenuName[1], Length(nMenu)); //??? funzt wahrscheinlich nicht. Müsste genaues Stringformat dazu kennen.
    FCommand.MenuName := FIniFile.ReadString('Command','Menuname',''); //So geht es wohl leider nicht, weil FCommand.Menuname -> ShortString!
    FCommand.DirName := FIniFile.ReadString('Command','Directory','');
    FCommand.ProgName := FIniFile.ReadString('Command','Exename','');  //Das funktioniert nicht so einfach, aber wie dann?
    FCommand.CfgFile := FIniFile.ReadString('Command','CfgFile','');
    FCommand.Options := FIniFile.ReadString('Command','Options','');

Wenn ich eine direkte Zuweisung ReadString an ShortString vornehme wird das hier nicht richtig ausgeführt:
Delphi-Quellcode:
if FCommand.MenuName = 'Mein Tool'
      then FCommand.OptionsDialog := TCommandOptOptDlg.Create(self)
Der Dialog wird nicht zugewiesen, also wird wohl der String fehlerhaft sein.

Uwe Raabe 6. Nov 2019 22:05

AW: Strin an ShortString zuweisen, wie?
 
Du unterliegst einem Irrtum: Ein
Delphi-Quellcode:
array[0..31] of Ansichar
ist kein ShortString! Einen vergleichbaren ShortString würde man mit
Delphi-Quellcode:
string[31]
deklarieren.

Kurze String-Typen

blawen 6. Nov 2019 22:23

AW: Strin an ShortString zuweisen, wie?
 
Wieso verwendest Du Shortstring?

Wenn es um den Speicherplatz geht, hast Du hoffentlich dies beachtet:
Zitat:

Ein ShortString hat eine Länge von 0 bis 255 Einzelbyte-Zeichen. Obwohl sich seine Länge dynamisch ändern kann, beträgt die statische Speicherplatzzuweisung immer 256 Bytes. Im ersten Byte wird die Länge des Strings gespeichert, die restlichen 255 Byte stehen für die Zeichen zur Verfügung.
Zitat:

UnicodeString-Variablen, denen kein Anfangswert zugewiesen wurde, enthalten einen String der Länge Null (0).
Ansonsten funktioniert das Zuweisen grundsätzlich wie man es vermuten würde.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  S     : String;
  ShortS : ShortString;

begin
  S := 'String';
  ShortS := S;
  Label1.Caption := ShortS;

  ShortS := 'ShortString';
  S     := ShortS;
  Label2.Caption := S;
end;
Dies müsste vom Prinzip m.E. eigentlich funktionieren, zumindest solange der der zugewiesene String nicht zu lange ist.
Delphi-Quellcode:
FCommand.ProgName := FIniFile.ReadString('Command','Exename',''); //Das funktioniert nicht so einfach, aber wie dann?

blawen 6. Nov 2019 22:30

AW: Strin an ShortString zuweisen, wie?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1450882)
Du unterliegst einem Irrtum: Ein
Delphi-Quellcode:
array[0..31] of Ansichar
ist kein ShortString! Einen vergleichbaren ShortString würde man mit
Delphi-Quellcode:
string[31]
deklarieren.

Hätte mir auch auffallen sollen, dies stammt ja aus der "C"-Ecke ;-)

cpux86 7. Nov 2019 06:03

AW: Strin an ShortString zuweisen, wie?
 
Warum aber funktioniert dann die Abfrage

Delphi-Quellcode:
if FCommand.MenuName = 'Mein Tool'
******then FCommand.OptionsDialog := TCommandOptOptDlg.Create(self)
nicht?

Zitat:

Zitat von blawen
Delphi-Quellcode:
Dies müsste vom Prinzip m.E. eigentlich funktionieren, zumindest solange der der zugewiesene String nicht zu lange ist.
FCommand.ProgName := FIniFile.ReadString('Command','Exename',''); //Das funktioniert nicht so einfach, aber wie dann?

Tut es aber leider nicht. Der String enthält bei Progname nur den Namen der .exe Datei, der ist auf keinen Fall zu lang, bei den üblichen .exe Dateinamen. Der Menuname hat maximal 31 Zeichen, weil längere Strings da sinnlos sind.


Ist eventuell das hier die Ursache:

FMenuname ist immerhin ein AnsiString Array.
Delphi-Quellcode:
procedure TRegisteredCommand.SetMenuName(const Value: ShortString);
var i: Integer; s: ShortString;
begin
  for i := 1 to Length(Value) do FMenuName[i-1] := Value[i];

end;

function TRegisteredCommand.GetMenuName: ShortString;
var i: Integer; s: ShortString;
begin
  s := '';
  i := 0;
  while (FMenuName[i] >= ' ') do
  begin
    s := s + FMenuName[i];
    inc(i);
  end;

  Result := s;
end;
[OT]
Sorry für den Doppelaccount, bin schöni, kann mich aber schon lange nicht mehr als Schöni einloggen. Wollte das gestern ändern und zukünftig wieder als schöni hier aktiv sein statt DualCoreCpu, dabei gibt mir die DP auf "Kennwort vergessen" aber den Usernamen cpux86. Da kann ich auch bei DualCoreCpu bleiben oder eben dem jetzigen Usernamen.
[/OT]

Luckie 7. Nov 2019 06:56

AW: Strin an ShortString zuweisen, wie?
 
Delphi-Quellcode:
if FCommand.MenuName[index] = 'Mein Tool' then

Incocnito 7. Nov 2019 07:15

AW: Strin an ShortString zuweisen, wie?
 
Hi,

"if ShortString = String then" sollte gehen, notfalls hart casten
also "if (String(FCommand.MenuName) = 'Mein Tool') then", aber
Delphi-Quellcode:
function TRegisteredCommand.GetMenuName: ShortString;
var i: Integer; s: ShortString;
begin
  s := '';
  i := 0;
  while (FMenuName[i] >= ' ') do
  begin
    s := s + FMenuName[i];
    inc(i);
  end;

  Result := s;
end;
ist mir etwas zu gefährlich ... dann lieber:
Delphi-Quellcode:
function TRegisteredCommand.GetMenuName: ShortString;
var i: Integer;
begin
  Result := '';
  for i := Low(FMenuName= to High(FMenuName) do
  begin
    if (FMenuName[i] < ' ') then Break;
    Result := Result + FMenuName[i];
  end;
end;
Die zusätzliche Variable "s" hab ich auch mal rausgenommen.
Aber mir geht es eigendlich darum, dass das Array evtl. nicht initialisiert ist,
und dementsprechend er lustig über den Tellerrand laufen könnte ... glaube ich ... theoretisch ... unter Umständen ... Aber vielleicht ist das schon das ganze Problem.

LG
Incocnito

cpux86 7. Nov 2019 07:30

AW: Strin an ShortString zuweisen, wie?
 
Zitat:

Zitat von Luckie (Beitrag 1450894)
Delphi-Quellcode:
if FCommand.MenuName[index] = 'Mein Tool' then

Nein, sorry, FMenuName ist ein AnsiChar Array!

Zitat:

Zitat von Incocnito
Aber mir geht es eigendlich darum, dass das Array evtl. nicht initialisiert ist,
und dementsprechend er lustig über den Tellerrand laufen könnte ... glaube ich ... theoretisch ... unter Umständen ... Aber vielleicht ist das schon das ganze Problem.

Nein, das ist es nicht, ich habe diese Felder mittels FillChar(FMenuName, Sizeof(FMenuName),$00) mit Nullbytes initialisiert.

Eher ist es was in dieser Richtung:

Delphi-Quellcode:
//von der Embarcadero Webseite (Doku zu Strings):
function ShortStringToString(Value: array of Byte): String;
var
  B: TBytes;
  L: Byte;
begin
  Result := '';
  L := Value[0];
  SetLength(B, L);
  Move(Value[1], B[0], L);
  Result := TEncoding.Ansi.GetString(B);
end;
Ich habe das TEncoding.Ansi.GetString() nicht drin.

Mein Array FMenuName ist AnsiChar. Von da will ich auf ShortString zuweisen.

bcvs 7. Nov 2019 08:00

AW: Strin an ShortString zuweisen, wie?
 
Zitat:

Zitat von DualCoreCpu (Beitrag 1450881)
Wegen säterer Absicht, die Commands in einer Datei abzulegen, habe ich hier Shortstring gewählt. Wenn ich die Kommandos aber nun in einer Ini Datei ablegen will, tritt beim Wieder einlesen das Problem auf, dass ja Inifile.ReadString() einen String, nicht ShortString zurück gibt. Wie kann ich diesen String nun an ShortString zuweisen?

Wieso überhaupt das ganze rumgezerre mit Array of AnsiChar und Shortstring. Wieso nimmst du nicht einfach einen String und fertig.
Oder was ist das für eine Datei, in der du die Commands ablegen willst? Nimmt die keine normalen Strings?

cpux86 7. Nov 2019 08:09

AW: Strin an ShortString zuweisen, wie?
 
Zitat:

Zitat von bcvs
Wieso überhaupt das ganze rumgezerre mit Array of AnsiChar und Shortstring. Wieso nimmst du nicht einfach einen String und fertig.
Oder was ist das für eine Datei, in der du die Commands ablegen willst? Nimmt die keine normalen Strings?

Weil ich dem Irrtum unterlegen war, dass ich dann einfacher die Daten in eine Datei schreiben könne. Nun aber habe ich den hier bekannt gewordenen Mehraufwand.

Habe meinen Code jetzt so umgestellt:

Delphi-Quellcode:
var
  nMenu: String;
  nPath: String;
  nProg: String;
  nConf: String;
  nOpts: String;

  sMenu: ShortString;
  sPath: ShortString;
  sProg: ShortString;
  sConf: ShortString;
  sOpts: ShortString;
  C: AnsiChar; // ist ein Byte groß, wie ich das für Shortstring brauche


    FCmd := TRegisteredCommand.Create;
    FInifile := TIniFile.Create('editor.ini');
    nMenu := FIniFile.ReadString('Command','Menuname','');
    nPath := FIniFile.ReadString('Command','Directory','');
    nProg := FIniFile.ReadString('Command','Exename','');
    nConf := FIniFile.ReadString('Command','CfgFile','');
    nOpts := FIniFile.ReadString('Command','Options','');

    StringToShortString(nMenu, sMenu);
    StringToShortString(nPath, sPath);
    StringToShortString(nProg, sProg); //Hier sollte doch dann eine korrekte Anpassung dank TEncoding erfolgen?
    StringToShortString(nConf, sConf);
    StringToShortString(nOpts, sOPts);

    FCmd.MenuName := sMenu;
    FCmd.DirName := sPath;
    FCmd.ProgName := sProg;
    FCmd.CfgFile := sConf;
    FCmd.Options := sOpts;
    FIniFile.Free;
      ShowMessage('Menüname = ' + FCmd.MenuName);
Aber FCmd.MenuName ist nach wie vor leer.

Die Umwandlungsroutine sieht so aus, von der Emba Webseite hier: http://docwiki.embarcadero.com/CodeE...String_(Delphi)

Delphi-Quellcode:
procedure StringToShortString(const S: String; var RetVal);
var
  L: Integer;
  I: Byte;
  C: Char;
  P: PByte;
  B: TBytes;
begin
  L := Length(S);
  if L > 255 then
    raise EShortStringConvertError.Create('Strings longer than 255 characters cannot be converted');
  SetLength(B, L);
  P := @RetVal;
  P^ := L;
  Inc(P);
  B := TEncoding.Ansi.GetBytes(S);
  Move(B[0], P^, L);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:45 Uhr.
Seite 1 von 2  1 2      

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