Solved

StrToVar ? :)

Posted on 2004-03-30
19
1,568 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

[Webinar] Code, Load, and Grow

Managing multiple websites, servers, applications, and security on a daily basis? Join us for a webinar on May 25th to learn how to simplify administration and management of virtual hosts for IT admins, create a secure environment, and deploy code more effectively and frequently.

Question has a verified solution.

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

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

751 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