Solved

StrToVar ? :)

Posted on 2004-03-30
19
1,498 Views
Last Modified: 2012-05-04
Is there any way to make this kind of Procedure?

like

...
a : integer = 0;
b : integer = 0;
c : integer = 0;
d : integer = 0;
e : integer = 0;
...

Procedure StrToVar (variable : String ; value : integer);
begin
  ?? // well i need something different then "if variable = 'a' then" :)  
      // I want something that i can use with any variables ( int type )
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  StrToVar(edit1.text,strtoint(edit2.text)); // where edit1.text is 'a' and edit2.text is '5'
end;

Is there any way to make it work ? btw if its to much complicated i can incresse the points :)


thx in Advance
0
Comment
Question by:furmiga
  • 8
  • 4
  • 4
  • +2
19 Comments
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
to limit on using many if thens, you could use a case statement...I know, I know, case statements are for ordinal types,
well, maybe this can help!

http://groups.google.com/groups?q=Delphi++%2B+Strings+%2B+Case&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=3949265d%240%2462934%2445beb828%40newscene.com&rnum=3


The only other way I can thing of is to create a class wrapper  which holds the String and value representation.

type

 TWrap
  Name: String;
  Value: Integer;
 end;

var

 Wrap: TWrap;

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Or you can create a TStringList, populate it with the values you are looking
for pass it to this function


Function GetValue(Name: String; List: TStrings): Integer
begin
 case List.IndexOf(Name) of
 0: result:= 100;
 1: result:= 200;
 etc. etc.
 end;
end.

Shane
0
 
LVL 17

Expert Comment

by:mokule
Comment Utility
You can try like this

var
  s: TStrings;
  ind: integer;


begin
  s:= TStringList.Create;
  s.AddObject('one',TObject(12));
  s.AddObject('two',TObject(257));
  s.AddObject('three',TObject(311));
................


usage


var
  ind: integer;
begin
  ind :=  s.IndexOf(Edit1.Text);
  if ind >= 0 then
    Edit2.Text := IntToStr(integer(s.Objects[ind]))
  else
    Edit2.Text := 'NotFound';
0
 
LVL 17

Expert Comment

by:mokule
Comment Utility
Another nice solution is
TRegIniFile
and
function ReadInteger(const Section, Ident: String; Default: Longint): Longint;

0
 
LVL 26

Expert Comment

by:Russell Libby
Comment Utility
Another possible...

var
  // IntArray
  IntArray:      Array ['A'..'Z'] of Integer = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

implementation
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var  c:       Char;
begin

  c:='A';
  IntArray[UpCase(c)]:=5;
  ShowMessage(IntToStr(IntArray['A']));

end;

----------

Regards,
Russell
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Wow, the possibilities just keep adding up!

<SMILE>

Shane
0
 
LVL 12

Expert Comment

by:esoftbg
Comment Utility
it could be
1. way:
var
  AI:  array['a'..'z'] of Integer;

1. way:
type
  TNVRec = record
    Name:  string;
    Value:  Integer;
  end;
//  TNVArr = array of TNVRec;
//  TNVArr = array[1..25] of TNVRec;
  TNVArr = array [0..65535] of TNVRec;

var
  NVArr:  TNVArr;

emil
0
 
LVL 7

Author Comment

by:furmiga
Comment Utility
okie.. lemmi try explain again ( after i read the topic i was like confused heh )

var
  Form1: TForm1;
  armor_lvl : integer = 0;
  life : integer = 0;
  gold : integer = 0;        

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
var
variables, VarPart , VarValue: String;
I , total : integer;
begin

     //1 - I have a Indy client TCP that sends the command "GetChanged" to the server.
     WriteLn('GetChanged');

     //2 - The server writes me all variables changed since the last command and I save it into a var.
     variables := ReadLn;

     //3 - now supose this time the variables value is '@Armor_lvl=3@life=45@gold=4555'

     //4 - now i count how many '@' are in variables and save it in total

     for I := 0 to total do
     begin
          // using the var VarPart i store the ' I ' part of the string like: ( using a function..... )
          VarPart = 'Armor_lvl';
          // using the var VarValue i store the ' I ' part of the string like: ( using a function..... )
          VarValue = '3';
          // now this is what i want. I want to modify the REAL variables armor_lvl, life and gold
          using the VarPart / VarValue variables without using the if then statement.
          // something like
          StrToVar(VarPart) := StrToInt(VarValue)
     end;
end;

I guess now u guys can undertand me better :)

 rllibby I liked your suggestion but im still waiting for a StrToVar answer since if i use an array to save my vars all the program will have to be build in a array mode and every time i need to call a var i will have to call the array and i dont know if this can be a good way.


Well I ll add more 100 points. This can help me a bit :)
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility

Send the entire string to a TStringList as was suggested above, parsing out the name & values and using the
TSTringList AddObject method to add it to the list

OTTOMH something like

procedure  BuildList(List: TStrings; Data: String);
var
 I: Integer;
 Name: String;
 Value: Integer;
 tmpStr: String;
begin

 for I:= 2 to length(Data) do
 begin
  if (Data[I] <> '@') then
   Name:= Name + Data[I]
  else
   List.AddObject(Name,TObject(0));

 for I:= 0 to List.Count - 1 do
 begin
 List.Objects[I]:= StrToInt(Copy(List[I],pos('=',List[I]),Length(List[I])));
 tmpStr:= List[I];
 Delete(tmpStr, pos('=',List[I]) + 1,Length(List[I]));
 List[I]:= tmpStr;
 end;  

end;

Shane
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
The indexes may be off give or take a number, - it was OTTOMH

And, Im sure someone can make it more robust - <smile>
0
 
LVL 17

Expert Comment

by:mokule
Comment Utility
As in my solution.
It should work
 
var
  ind: integer;
begin
  ind :=  s.IndexOf(VarPart);
  if ind >= 0 then
    s.Delete(ind);

  s.AddObject(VarPart,TObject(VarValue));
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
OOps, sorry, a typo


 for I:= 2 to length(Data) do

< begin> "remove"
 
 if (Data[I] <> '@') then
   Name:= Name + Data[I]
  else
   List.AddObject(Name,TObject(0));

shane
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 225 total points
Comment Utility
Or in object form...


uses
  Windows, SysUtils, Classes;

type
  TIntArray      =  class(TObject)
  private
     FVariables: TStringList;
     FVarDelim:  Char;
     FValDelim:  Char;
  protected
     procedure   SetValue(Index: String; Value: Integer);
     procedure   SetText(Value: String);
     function    GetVariable(Index: Integer): String;
     function    GetText: String;
     function    GetValue(Index: String): Integer;
     function    GetCount: Integer;
  public
     constructor Create(VarDelim, ValDelim: Char);
     destructor  Destroy; override;
     property    Variables[Index: Integer]: String read GetVariable;
     property    Values[Index: String]: Integer read GetValue write SetValue;
     property    VarDelimiter: Char read FVarDelim write FVarDelim;
     property    ValDelimiter: Char read FValDelim write FValDelim;
     property    Text: String read GetText write SetText;
     property    Count: Integer read GetCount;
  end;

implementation

procedure TIntArray.SetText(Value: String);
var  lpszTemp:   PChar;
     lpszCur:    PChar;
     lpszVar:    PChar;
     lpszVal:    PChar;
begin

  // Allocate memory for parsing
  lpszTemp:=AllocMem(Succ(Length(Value)));
  try
     // Set current string pointer
     lpszCur:=lpszTemp;
     // Copy passed in string
     StrPCopy(lpszCur, Trim(Value));
     // Iterate while we have string
     while (lpszCur^ > #0) do
     begin
        // Skip past empty variables, or starting marker
        while (lpszCur^ = FVarDelim) and (lpszCur^ > #0) do Inc(lpszCur);
        // Break if at string end
        if (lpszCur^ = #0) then break;
        // Get the variable name
        lpszVar:=lpszCur;
        // Skip to the value delimiter
        while (lpszCur^ <> FValDelim) and (lpszCur^ > #0) do Inc(lpszCur);
        if (lpszCur^ = #0) then break;
        // Null out and set the value start
        lpszCur^:=#0;
        Inc(lpszCur);
        lpszVal:=lpszCur;
        // Find the end of the value
        while (lpszCur^ <> FVarDelim) and (lpszCur^ > #0) do Inc(lpszCur);
        // Terminate if we are sitting on a variable delimiter
        if (lpszCur^ = FVarDelim) then
        begin
           lpszCur^:=#0;
           Inc(lpszCur);
        end;
        // Add the variable setting
        SetValue(lpszVar, StrToIntDef(lpszVal, 0));
     end;
  finally
     // Free allocated memory
     FreeMem(lpszTemp);
  end;

end;

function TIntArray.GetText: String;
var  dwIndex:    Integer;
begin

  // Build result string
  result:=FVarDelim;
  for dwIndex:=0 to Pred(FVariables.Count) do
  begin
     result:=result+FVariables[dwIndex]+FValDelim+IntToStr(Integer(FVariables.Objects[dwIndex]));
  end;

end;

function TIntArray.GetVariable(Index: Integer): String;
begin

  // Return the variable name
  result:=FVariables[Index];

end;

procedure TIntArray.SetValue(Index: String; Value: Integer);
var  dwIndex:    Integer;
begin

  // Search for variable
  if FVariables.Find(Index, dwIndex) then
     // Update
     FVariables.Objects[dwIndex]:=TObject(Value)
  else
     // Add new
     FVariables.AddObject(Index, TObject(Value));

end;

function TIntArray.GetValue(Index: String): Integer;
var  dwIndex:    Integer;
begin

  // Search for variable
  if FVariables.Find(Index, dwIndex) then
     result:=Integer(FVariables.Objects[dwIndex])
  else
     result:=0;

end;

function TIntArray.GetCount: Integer;
begin

  // Return count of variables
  result:=FVariables.Count;

end;

constructor TIntArray.Create(VarDelim, ValDelim: Char);
begin

  // Perform inherited
  inherited Create;

  // Set starting values
  FVariables:=TStringList.Create;
  FVarDelim:=VarDelim;
  FValDelim:=ValDelim;

end;

destructor TIntArray.Destroy;
begin

  // Cleanup
  FVariables.Free;

  // Perform inherited
  inherited Destroy;

end;

-------------------
usage

var  dwIndex:    Integer;
begin

  with TIntArray.Create('@', '=') do
  begin
     Text:='@Armor_lvl=3@life=45@gold=4555';
     ShowMessage(Text);
     for dwIndex:=0 to Pred(Count) do
        ShowMessage(Format('%s = %d', [Variables[dwIndex], Values[Variables[dwIndex]]]));
  end;

end;


---

Russell


0
 
LVL 26

Expert Comment

by:Russell Libby
Comment Utility
My bad on the constructor...

constructor TIntArray.Create(VarDelim, ValDelim: Char);
begin

  // Perform inherited
  inherited Create;

  // Set starting values
  FVariables:=TStringList.Create;
  FVariables.Sorted:=True;                // <----- Add the following 2 lines
  FVariables.Duplicates:=dupIgnore;   //  
  FVarDelim:=VarDelim;
  FValDelim:=ValDelim;

end;

----------

Russell
0
 
LVL 7

Author Comment

by:furmiga
Comment Utility
Russell u kinda crazy :) ty man it worked fine.
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
All of that just to parse that line of text -- OK, what ever floats your boat - :)

Shane
0
 
LVL 17

Expert Comment

by:mokule
Comment Utility
A gift for furmiga
// parsing a line

uses RegExpr;


procedure TForm1.Parse(AText: string);
var
  xxx: TRegExpr;
begin
  ListBox1.Clear;
  xxx := TRegExpr.Create;
  xxx.Expression := '(@)(\w+)(=)(\d+)';

  if xxx.Exec(AText) then
  repeat
    ListBox1.Items.Add(xxx.Match[2]+','+xxx.Match[4])
  until not xxx.ExecNext;
  xxx.Free
end;

Marek
;-)
0
 
LVL 26

Expert Comment

by:Russell Libby
Comment Utility

I was trying to demonstrate the purpose of object encapsulation. I mean, it takes 20 lines of code just to SET the information, and it still means maintaining the list in the application code. If the big picture is taken into consideration, then the app is going to need to read/write values itself (using the var name).( and these variables may/may not already exist). The app may also need to build a string of the variables to send the changed info back to the server. So now instead of creating a string list to maintain this, you create a lightweight object that handles all aspects of the data.

So considering the full scope of use, 160 lines of code is minimal, plus its encapsulated.

Russell
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
No, No, dont get me wrong Russell, I know what you were doing....

I also know what he wanted, this is his second post i believe. I think he also posted the question regarding sending the commands back & fourth via CLient?Server communications.

If he would have hued my suggestions (assuming it was him) from his first post, then he would have not needed all this..

Shane
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now