我正在使用inifile来存储我用来替换文件中其他值的值,例如A,BA = B,但是如果我在值B之前有空格,那么当读取EG A = B时忽略该值仍然只读'B'而不是'B',有没有人知道如何解决这个问题,我使用的是Delphi 7,所以我不能使用StrictDelimiter选项。
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;
由于
科林
答案 0 :(得分:5)
TIniFile.ReadSectionValues最终使用Windows API函数GetPrivateProfileString从ini文件中读取键值。 GetPrivateProfileString将删除任何前导和尾随空格以及字符串周围的任何引号。
这意味着该行
[ key = value1 value2 value3 ]
将返回与行
相同的值 [ key=value1 value2 value3 ]
(添加方括号以显示额外的空格)。
为了保留任何前导和尾随空格,在将字符串写回ini时,必须将字符串用单引号或双引号括起来。
当GetPrivateProfileString删除任何周围的引号(单引号或双引号)时,您不需要在从ini文件中读取值时将其删除。
要添加引号,您不应使用函数AnsiQuotedStr函数,因为Francois提到了(编辑,除非您特别注意选择一个非常不可能在首先是字符串)。 AnsiQuotedStr将添加周围的双引号,但它也会使字符串中已有的双引号加倍。虽然当你随后使用AnsiDequoteStr时这是期望的行为,但是当你使用TIniFile读取值时,GetPrivateProfileString将删除周围的quoatation标记,但它不会对嵌入的标记进行去加倍。
因此,如果您要使用TIniFile从文件中读取值并希望保留前导和尾随空格,则必须自己添加周围的引号并确保任何嵌入的引号不会加倍(或者您用TIniFile阅读后,他们必须自己去掉它们。
答案 1 :(得分:3)
在写入INI文件时,您可能希望将字符串括在特殊引号(不是常规单引号或双引号)中以保留空格(与使用包含空格的长文件名的双引号相同)并在读取时删除引号回来了。
您可以使用AnsiQuotedStr
中的AnsiDequotedStr
和SysUtils
来完成此操作。 (不知道它们是否存在于D7中)
更新:正如Marjan所指出的,如果您使用普通的TIniFile ,则不得使用常规'或',因为它们将被删除,而中间的那些人将保持不受影响 这有一个令人讨厌的副作用,如果你明白地写下你刚刚读到的内容,那么你不会得到相同的值(除非你总是在写作之前在两端特别添加引号)。
如果您使用TMemInifile 一次性加载内存中的IniFile以加快进一步的读写操作,则不会发生此行为。 常规报价不会被删除,您可以使用它们 尽管如此,如果您计划在文本编辑器中修改IniFile,并且您希望将常规引号作为值的一部分,那么使用特殊引号将字符串括起来并确保它们在已经存在的情况下加倍时仍然很有用。 / p>
底线: AnsiQuotedStr
和AnsiDequotedStr
带有特殊的QuoteChar 可以通过对称方式进行读写,无论您使用的是TIniFile还是TMemIniFile 都一样。
答案 2 :(得分:2)
也许您可以在保存StringList之前使用StringReplace将所有前导空格更改为您的数据永远不会包含的某些字符,如@符号?)然后在读取数据时执行相反操作?