Solved

StrToVar ? :)

Posted on 2004-03-30
19
1,528 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
ID: 10714962
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
ID: 10715016
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
ID: 10715157
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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 17

Expert Comment

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

0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 10715447
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
ID: 10715480
Wow, the possibilities just keep adding up!

<SMILE>

Shane
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 10715558
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
ID: 10716242
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
ID: 10716418

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
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10716431
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
ID: 10716440
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
ID: 10716448
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
ID: 10716968
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
ID: 10717186
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
ID: 10717701
Russell u kinda crazy :) ty man it worked fine.
0
 
LVL 11

Expert Comment

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

Shane
0
 
LVL 17

Expert Comment

by:mokule
ID: 10718014
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
ID: 10718158

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
ID: 10718247
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

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Intraweb download file link ? 1 133
Convert a string into a TDateTime 5 60
can't find the executable in Simulator 1 90
how to change, disabled button color FMX ? 1 32
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…

770 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