0

I would like to use a TStringList to parse the output from "ipconfig /all".

If I use AddStrings, the entire return string ends up in the first element. I have tried to use LoadFromStream but the compiler gives me

no matching member function for call to 'LoadFromStream'

and

candidate function not viable: no known conversion from 'String' (aka 'System::UnicodeString') to 'System::Classes::TStream *' for 1st argument

Any ideas on how I can get the String into a Stream, or another way to get the return String into my TStringList?

TStringList *IPConfig = new TStringList;
IPConfig->AddStrings(ExecuteExternalFile("ipconfig", "/all", false));  //everything returned ends up in one element defeating the purpose of using a TStringList
IPConfig->LoadFromStream(ExecuteExternalFile("ipconfig", "/all", false));  //won't compile
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
martinarcher
  • 137
  • 2
  • 9
  • Is each string managed in an instance of `String` or is it just one string with new line characters indicating the end of each string? Why not just have `ExecuteExternalFile` return a `TStringList`? – Captain Obvlious Aug 11 '16 at 20:10
  • 1
    You need to play with the `TStringList`'s `Delimiter` property if I'm remembering correctly. Been a while since I used the VCL. – user4581301 Aug 11 '16 at 20:18
  • ExecuteExternalFile is just returning one giant String with newline characters throughout. Is there a way to make ExecuteExternalFile return a TStringList? It's a Windows function so I thought it is what is is and I have to deal with the returned String as is? – martinarcher Aug 11 '16 at 20:24
  • It's not a function of Windows, it's part of the Borland libraries - either way you can't change it but you could wrap it if necessary. As @user4581301 pointed out you need to look at the `Delimeter` member of `TString`. – Captain Obvlious Aug 11 '16 at 20:34
  • This is going to sound stupid, but the best discussions on how to use the VCL are generally found browsing the delphi tag because that's where the VCL came from. Here's an example: http://stackoverflow.com/questions/2625707/split-a-string-into-an-array-of-strings-based-on-a-delimiter – user4581301 Aug 11 '16 at 20:40
  • "*parse to output from an "ipconfig /all"*" - is there a reason why you are spawning `ipconfig` at all instead of just using relevant Win32 API functions that return the desired data directly to your code? – Remy Lebeau Aug 14 '16 at 18:09

2 Answers2

0

Thanks for steering me back to the Delimiter property. I revisited it and found there is a bug in it that requires you to set the StrictDelimiter to true otherwise is will always delimit your text via a space. Now it works fine. Thanks!

IPConfig->StrictDelimiter = true;
IPConfig->Delimiter = '\n';
IPConfig->DelimitedText = ExecuteExternalFile("ipconfig", "/all", false);
user4581301
  • 33,082
  • 7
  • 33
  • 54
martinarcher
  • 137
  • 2
  • 9
  • 3
    That is not a bug. That is intentional [and documented](http://docwiki.embarcadero.com/Libraries/en/System.Classes.TStrings.DelimitedText) behavior: "*If `StrictDelimiter` is set to False, the space character is also interpreted as a delimiter, regardless of the value of `Delimiter`. This is not true when the space character occurs between quotation marks.*" – Remy Lebeau Aug 11 '16 at 22:52
  • It seems normal that the space is still used as a delimiter by default when a specific delimiter is not set but it seems odd and an unexpected behavior to continue to use space after setting a specific delimiter. It threw me for a loop and several others as I was searching for a solution on the net. Oh well, I guess after your burnt you don't as easily forget it in the future. :) Thanks for the clarification Remy! – martinarcher Aug 12 '16 at 12:56
  • It may seem odd to you, but it is the intended and documented behaviour, so it is not a bug. – Rudy Velthuis Aug 13 '16 at 20:06
0

You can use a TStringStream with LoadFromStream():

TStringList *IPConfig = new TStringList;
TStringStream *Strm = new TStringStream(ExecuteExternalFile("ipconfig", "/all", false));
IPConfig->LoadFromStream(Strm);
delete Strm;
...
delete IPConfig;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770