Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

StrToVar ? :)

Posted on 2004-03-30
19
Medium Priority
?
1,628 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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 900 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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

722 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