I want to create key-value pairs in a TStringList
in a C++Builder 6 VCL application.
I know how to read the Names and Values out, but I can't find a way to create the paired entries that works.
I tried, for example:
TStringList *StringList = new TStringList();
StringList->Add("Sydney=2000");
StringList->Names[0]
returns "Sydney"
but StringList->Values[0]
returns ""
.
I know this works in CB11, but I can't find a way in BCB6.
You are creating the named pair correctly (in recent versions, you can use the AddPair()
method instead).
The Values[]
property takes a key name, not an index (and always has, so your claim that the code you have shown works in CB11 is incorrect), eg:
TStringList *StringList = new TStringList;
StringList->Add("Sydney=2000");
ShowMessage(StringList->Names[0]); // shows "Sydney"
ShowMessage(StringList->Values["Sydney"]); // shows "2000"
delete StringList;
The only reason that using Values[0]
even compiles at all is because the property takes a System::String
, and in C++ a String
can be constructed directly from an integer value (in Delphi, you have to make that conversion explicitly using the SysUtils.IntToStr()
function).
The ValueFromIndex[]
property, on the other hand, takes an index, but it wasn't available until Delphi 7 (and thus did not appear in C++Builder until CB2006), eg:
TStringList *StringList = new TStringList;
StringList->Add("Sydney=2000");
ShowMessage(StringList->Names[0]); // shows "Sydney"
ShowMessage(StringList->ValueFromIndex[0]); // shows "2000"
delete StringList;
So, because TStringList
in C++Builder/Delphi 6 did not have the ValueFromIndex[]
property yet, if you want to access a value by index then you will have to use the Names[]
property to get the key name needed for the Values[]
property, eg:
TStringList *StringList = new TStringList;
StringList->Add("Sydney=2000");
String name = StringList->Names[0];
ShowMessage(name); // shows "Sydney"
ShowMessage(StringList->Values[name]); // shows "2000"
delete StringList;
Alternatively, you can extract the value manually (so you don't have to waste time searching the list for a matching name), eg:
TStringList *StringList = new TStringList;
StringList->Add("Sydney=2000");
String name = StringList->Names[0];
ShowMessage(name); // shows "Sydney"
String s = StringList->Strings[0];
String value = s.SubString(name.Length() + 2, MaxInt);
ShowMessage(value); // shows "2000"
delete StringList;