Reading inline namespace issue in Stringlist

I use inifile to store the values ​​that I use to replace other values ​​in the file, for example A with BA = B, which works fine, but if I blank to the value of B, this is ignored when reading in EG A = B still reads like "B", not "B", does anyone know how I can fix this, I use Delphi 7, so I can not use the StrictDelimiter parameter.

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

+4
source share
3 answers

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

That means the string

[ key = value1 value2 value3 ]

will return the same value as the string

[ key=value1 value2 value3 ]

(square brackets added to show extra spaces).

To preserve any leading and trailing spaces, you will have to enclose your lines in single or double quotation marks when writing them back to ini.

Since GetPrivateProfileString removes any surrounding quotes (single or double), you do not need to remove them when you read the values ​​from the ini file.

To add quotes, you should NOT use the AnsiQuotedStr function, as François mentioned ( change , unless you take special care to select a char quote, which is very unlikely in the string in the first place). AnsiQuotedStr will add surrounding double quotes, but will also double any double quotes already on the line. Although this is the desired behavior when you subsequently use AnsiDequoteStr, it is not when you use TIniFile to read values, since GetPrivateProfileString removes the surrounding quota labels, but will not release the built-in ones.

So, if you are going to read values ​​from a file using TIniFile and want to keep leading and trailing spaces, you will need to add surrounding quotes yourself and make sure that any embedded quotes are not doubled (or you will have to de-double them after reading them with TIniFile).

+5
source

You may want to enclose your lines in special quotation marks (rather than ordinary single or double quotes) to preserve spaces (the same as using double quotes with long file names containing spaces) when writing to an INI file and removing quotes when reading backwards.
You can do this with AnsiQuotedStr and AnsiDequotedStr from SysUtils . (don't know if they existed in D7, though)

Update: as Marjan pointed out, you should not use regular 'or if you use the usual TIniFile , as they will be removed from both ends, while those in the middle will remain untouched.
This has an unpleasant side effect: if you clearly write what you just read, then you will not get the same value (unless you add quotes at both ends before writing).

This behavior does not occur if you use TMemInifile to load IniFile in memory immediately to speed up further reading and writing. regular quotes are not removed , and you can use them.
However, if you plan to modify IniFile in a text editor, and you expect regular quotes as part of the values, it’s still useful to use special quotation marks to include strings and ensure that they double if some of them already exist.

On the bottom line: AnsiQuotedStr and AnsiDequotedStr with a special QuoteChar will work symmetrically for reading and writing, regardless of whether you use TIniFile or TMemIniFile anyway.

+3
source

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

+2
source

All Articles