tags:

views:

163

answers:

3

I am using the inifile to store values which I use to replace other values in a file for example A with B A=B which works fine however if I a space before the value B this is Ignored when reading in EG A= B is still read in as just 'B' rather than ' B', does anyone have any idea how I can work fix this, I am using Delphi 7 so I cannot use the StrictDelimiter option.

procedure ReadIntoVList(const aSection:string;AValueList:TValueListEditor);
var
  IniFile:TIniFile;
  SL: TStringList;
  i: Integer;
begin
   SL := TStringList.Create;
   IniFile := TIniFile.Create(ChangeFileExt(Application.Exename, '.ini'));
   try
     IniFile.ReadSectionValues(ASection, SL);
     AvalueList.Strings.AddStrings(SL);
   finally
     StampIniFile.Free;
     SL.Free;
   end;
end;

Thanks

Colin

+1  A: 

Perhaps you could use StringReplace just before saving the StringList to change all the leading spaces to some character your data will never contain, like an @ sign?) and then do the opposite when reading the data in?

Robert Frank
+1  A: 

You may want to enclose your strings in special quotes (not the regular single or double) to preserve the spaces (same idea as using double quotes with long filenames containing blanks) when writing to the INI file and remove the quotes when reading back.
You can do that with AnsiQuotedStr and AnsiDequotedStr from SysUtils. (don't know if they existed in D7 though)

Update: as pointed out by Marjan, you must not use the regular ' or " if you use a plain TIniFile, as they will be removed on both ends, while those in the middle will be left untouched.
This has the nasty side effect that if you write plainly what you just read, then you're not ending up with the same value (unless you always specifically add quotes at both ends before writing).

This behavior does not happen if you use a TMenInifile to load the IniFile in memory all at once to speed up further reads and writes. The regular quotes are not removed and you can use them.
Nevertheless, if you plan on modifying the IniFile in a text editor, and you expect regular quotes as part of the values, it's still useful to use special quotes to enclose the strings and making sure they are doubled in case some were already there.

Bottom line: AnsiQuotedStr and AnsiDequotedStr with a special QuoteChar would work symetrically for reading and writing, whether you use a TIniFile or a TMemIniFile all the same.

François
You do not need to remove the quotes when reading the strings back if you use TIniFile. This is because TIniFile internally uses GetPrivateProfileString and this will remove the single or double quotation marks. MSDN: `If the string associated with lpKeyName is enclosed in single or double quotation marks, the marks are discarded when the GetPrivateProfileString function retrieves the string.`
Marjan Venema
@Marjan. The advantage of AnsiQuotedStr is that you can choose the QuoteChar to use. It's simple enough not to use the regular single or double Quotes. That's why I used "special quotes". I'll make my answer clearer.
François
+3  A: 

TIniFile.ReadSectionValues ultimately uses the Windows API function GetPrivateProfileString to read key values from the ini file. GetPrivateProfileString will remove any leading and trailing white space as well as any quotation marks surrounding the string.

This means that the line

[ key = value1 value2 value3 ]

will return the same value as the line

[ key=value1 value2 value3 ]

(square brackets added to show extra spaces).

In order to preserve any leading and trailing spaces, you will have to enclose your strings in either single or double quotation marks when writing them back into the ini.

As GetPrivateProfileString removes any surrounding quotation marks (single or double) you do not need to remove them when you read the values from the ini file.

To add the quotation marks you should NOT use a function AnsiQuotedStr function as Francois mentioned (edit unless you take special care to pick a quote char that is very very unlikely to be in the string in the first place). AnsiQuotedStr will add surrounding double quotation marks, but it will also double up any double quotation marks already in the string. While this is desired behaviour when you subsequently use AnsiDequoteStr, it is not when you use TIniFile to read the values as GetPrivateProfileString will remove the surrounding quoatation marks, but it will NOT de-double embedded ones.

So if you are going to read values from a file using TIniFile and want to preserve leading and trailing whitespace, you will have to add the surrounding quotation marks yourself and make sure that any embedded quotation marks are not doubled up (or you will have to de-double them yourself after reading them with TIniFile).

Marjan Venema
AnsiQuotedStr will add surrounding **whatever** QuoteChar you specify. Using a special quote (not ' nor ") would work without problem. You would then have a symetrical process for reading and writing, instead of writing with quotes while reading without, and never be guaranteed to read what you manually entered in the IniFile with a text editor.
François
@Francois: Ah yes, that is interesting idea, though you would have to choose your "quote" char very carefully, making it something that is very unlikely to be in the source string. Added a qualifier to my remark about AnsiQuotedStr use.
Marjan Venema