【问题标题】:reading 2 lines from IniFile从 IniFile 读取 2 行
【发布时间】:2011-07-03 03:38:20
【问题描述】:

再试一次。根据建议,添加我确实理解的代码。我很满意我必须在两行中保存 4 位信息,如下所示:

IniFile.WriteString('TestSection','Name','Country');
IniFile.WriteString('TestSection','City','Street');

我的问题更多是关于将这些信息重新加载到表单中。如果在我的 IniFile 中我保存了例如以下代码

[TestSection]
John=Uk
London=barlystreet
Mike=Spain
Madrid=eduardostrata
Emma=USA
New York=1st Avenue

IniFile 中的组成信息。通过上面的代码添加。 现在我的问题是:例如,当我在编辑框中输入 Mike 时,我如何加载其余的归属信息。(西班牙、马德里、eduardostrata)。

【问题讨论】:

  • 谢谢大家!这些是很好的答案,其他浪费时间的问题是我的错误。

标签: delphi ini


【解决方案1】:

这不是 INI 文件的工作方式。您保存 name=value 对,并且必须有办法将它们关联起来。

也许这可以帮助您入门:

Ini := TIniFile.Create(YourIniFileName);
try
  Ini.WriteString('Mike', 'Country', 'Spain');
  Ini.WriteString('Mike', 'City', 'Madrid');
  Ini.WriteString('Mike', 'Street', 'EduardoStrata');
finally
  Ini.Free;
end;

INI 文件中的结果包含:

[Mike]
Country=Spain
City=Madrid
Street=EduardoStrata

要加载回来:

var
  Country, City, Street: string;
  Ini: TIniFile;
begin
  Ini := TIniFile.Create(YourIniFilename);
  try
    Country := Ini.ReadString('Mike', 'Country', '<None>');
    City := Ini.ReadString('Mike', 'City', '<None>');
    Street := Ini.ReadString('Mike', 'Street', '<None>');
  finally
    Ini.Free;
  end;
  // Country, City, and Street now equal the values for 'Mike',
  // or they contain '<None>' if the section 'Mike' doesn't
  // exist or has no values for the variable.
end;

所以你大概可以弄清楚它是如何工作的。部分([] 中的部分)是人名,名称/值对是位置及其对应的值(例如,'Country=Spain')。

【讨论】:

  • 你还想提一下我认为的 ReadSections。
  • 是的,函数ReadSections 在这种情况下是必须的。你也可以考虑使用ReadSectionValues
  • 然而,这种方法的一个主要问题是,如果你有两个名字相同的人,它就行不通。事情发生了,你知道......
  • 我想过这一点,但认为最好提供一个起点(正如我在回答的第二段中提到的)。这对学习过程更好,不是吗? :-)
  • 将 name 设为一对和一个 autoinc 编号作为部分名称,然后我们就有了一个数据库:)
【解决方案2】:

您显然不了解 INI 文件的工作原理。如果约翰和戴夫都住在纽约怎么办?在一个 INI 文件中不能有两个同名的键。 (此外,您不应依赖每个部分中行的顺序。)

因此,您需要重新考虑如何保存数据。一个非常简单的解决方案是使用纯文本文件,其中每一行都是数据库中的一个项目,字段由例如垂直线 (|) 分隔:

John|Uk|London|barlystreet
Mike|Spain|Madrid|eduardostrata
Emma|USA|New York|1st Avenue.

如何读取这个文件?嗯,这是微不足道的,你应该知道如何做到这一点。如果您有一个非常具体的问题,请随时提出。

INI 文件的用途

那么,INI 文件有什么用呢?嗯,INI 文件的一个典型应用是保存程序设置。例如,当您退出文本编辑器时,它可能会将设置保存到 settings.ini:

[Font]
Name=Consolas
Size=10

[Behaviour]
AutoIndent=1
AutoReplace=1
AutoBrackets=1
BracketHighlight=1
SyntaxHighlight=1

[Window]
Width=800
Height=600
Maximized=0

等等。这是由

完成的
WriteString('Font', 'Name', Editor.Font.Name);
WriteInteger('Font', 'Size', Editor.Font.Size);

等等。并且下次启动应用程序时,它会读取文件来恢复设置:

Editor.Font.Name := ReadString('Font', 'Name', 'Consolas');
Editor.Font.Size := ReadInteger('Font', 'Size', 10);

等,其中最后一个参数是默认值(以防 INI 文件中缺少该字段)。请注意,在每个部分中,键是唯一的(并且必须是),并且我们不关心每个部分中键的相对顺序。

【讨论】:

    【解决方案3】:

    创建所需关系的最简单方法是在 1 行文本中包含用户的所有详细信息。这不是 INI 文件的工作。你的问题是如何解析字符串。

    首先,为什么要保存“重复密码”?这对我来说没有意义。通常,UI 会要求用户重复密码作为验证的一种形式,但这就是它的全部好处。存储它以供以后检索没有任何好处。

    我认为您需要保存用户的名字、姓氏和密码(3 个字符串)。看看下面这段代码。

    procedure SaveUserDetails(sFileName: string);
    var
      sFirstName, sLastName, sPassword: string;
      slUsers: TStringList;
    begin
      sFirstName := txtFirstName.Text;  // these could be from TEdit controls for example
      sLastName := txtLastName.Text;
      sPassword := txtPassword.Text;
      slUsers := TStringList.Create;
      slUsers.Add(sFirstName + ',' + sLastName + ',' + sPassword);
      slUsers.SaveToFile(sFileName);  // that has saved your stringlist to a file
      slUsers.Free;
    end;
    

    文件看起来像这样

    Shane,Warne,cricket
    

    现在,如何加载它...

    procedure LoadUserDetails(sFileName: string);
    var
      sFirstName, sLastName, sPassword: string;
      sTemp: string;
      slUsers: TStringList;
      iPos: integer;  // string position marker we'll use to split the string in 3
    begin
      slUsers := TStringList.Create;
      slUsers.LoadFromFile(sFileName); // this loads the file's contents into stringlist
      sTemp := slUsers[0];
      if (Length(sTemp) > 0) then // just to check that there is data there
      begin
        iPos := pos(',', sTemp); // get position of first comma (our "delimiter")
        sFirstName := Copy(sTemp, 0, iPos-1);  // firstName everything upto 1st comma
        sTemp := Copy(sTemp, iPos + 1, Length(sTemp)); // chop off bit we just read
        iPos := pos(',', sTemp); // get position of second comma
        sLastName := Copy(sTemp, 0, iPos-1);  // LastName everything upto 2nd comma
        sTemp := Copy(sTemp, iPos + 1, Length(sTemp)); // chop off bit we just read
        sPassword := sTemp; // that's it
      end;
      slUsers.Free;
    end;
    

    现在......这远非“好代码”,但现在你至少知道一种方法来做你的事。希望有帮助。

    【讨论】:

    • 不投票,但手动解析逗号或管道分隔值是一个坏主意。 TStrings.Delimiter/DelimitedText 和 `TStrings.CommaText' 更容易做到。
    • @Ken,同意了,但是这家伙显然就像你提到的那样在学习。
    • 一个try...finally...end 也不错,但是——再次——为了学习......
    • @Andreas,是的,我们也可以把整个事情变成 OO :-(
    猜你喜欢
    • 2023-04-04
    • 2011-07-13
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多