c++buildervclc++builder-6tstringlist

How to create Key-Value Pairs with TStringList in C++Builder 6?


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.


Solution

  • 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;