AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Strin an ShortString zuweisen, wie?

Strin an ShortString zuweisen, wie?

Ein Thema von DualCoreCpu · begonnen am 6. Nov 2019 · letzter Beitrag vom 7. Nov 2019
Antwort Antwort
Seite 1 von 2  1 2   
DualCoreCpu
(Gast)

n/a Beiträge
 
#1

Strin an ShortString zuweisen, wie?

  Alt 6. Nov 2019, 21:36
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
7.853 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Strin an ShortString zuweisen, wie?

  Alt 6. Nov 2019, 22:05
Du unterliegst einem Irrtum: Ein array[0..31] of Ansichar ist kein ShortString! Einen vergleichbaren ShortString würde man mit string[31] deklarieren.

Kurze String-Typen
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von blawen
blawen

Registriert seit: 30. Nov 2003
Ort: Luterbach (CH)
445 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Strin an ShortString zuweisen, wie?

  Alt 6. Nov 2019, 22:23
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.
FCommand.ProgName := FIniFile.ReadString('Command','Exename',''); //Das funktioniert nicht so einfach, aber wie dann?
Roland
  Mit Zitat antworten Zitat
Benutzerbild von blawen
blawen

Registriert seit: 30. Nov 2003
Ort: Luterbach (CH)
445 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Strin an ShortString zuweisen, wie?

  Alt 6. Nov 2019, 22:30
Du unterliegst einem Irrtum: Ein array[0..31] of Ansichar ist kein ShortString! Einen vergleichbaren ShortString würde man mit string[31] deklarieren.
Hätte mir auch auffallen sollen, dies stammt ja aus der "C"-Ecke
Roland
  Mit Zitat antworten Zitat
cpux86

Registriert seit: 24. Jun 2008
7 Beiträge
 
#5

AW: Strin an ShortString zuweisen, wie?

  Alt 7. Nov 2019, 06:03
Warum aber funktioniert dann die Abfrage

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

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]

Geändert von cpux86 ( 7. Nov 2019 um 06:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

AW: Strin an ShortString zuweisen, wie?

  Alt 7. Nov 2019, 06:56
if FCommand.MenuName[index] = 'Mein Toolthen
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
78 Beiträge
 
#7

AW: Strin an ShortString zuweisen, wie?

  Alt 7. Nov 2019, 07:15
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
  Mit Zitat antworten Zitat
cpux86

Registriert seit: 24. Jun 2008
7 Beiträge
 
#8

AW: Strin an ShortString zuweisen, wie?

  Alt 7. Nov 2019, 07:30
if FCommand.MenuName[index] = 'Mein Toolthen
Nein, sorry, FMenuName ist ein AnsiChar Array!

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.

Geändert von cpux86 ( 7. Nov 2019 um 07:41 Uhr)
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
489 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Strin an ShortString zuweisen, wie?

  Alt 7. Nov 2019, 08:00
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?
  Mit Zitat antworten Zitat
cpux86

Registriert seit: 24. Jun 2008
7 Beiträge
 
#10

AW: Strin an ShortString zuweisen, wie?

  Alt 7. Nov 2019, 08:09
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;

Geändert von cpux86 ( 7. Nov 2019 um 08:12 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 12:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf