String 链接4条信息并保存它们

String 链接4条信息并保存它们,string,delphi,save,String,Delphi,Save,保存、编辑和加载信息。我想加载的信息是我自己添加的。每行信息将包含4个部分(字符串、整数、字符串、整数)。通过4个独立的编辑框和一个按钮,我将把这些信息添加到一个“数据库”(不确定我是否需要一个数据库,或者是否可以通过类似Tstringlist的东西来完成)。每次点击按钮时,它都会在“数据库”中添加当时键入的内容 保存数据的唯一要求是,当我从列表中键入第一个字符串时,它可以将属于它的其余信息也放在备忘录框或编辑框中。所以我想我必须能够搜索。只是想让它尽可能简单。只有大约10到15行信息。如果可能

保存、编辑和加载信息。我想加载的信息是我自己添加的。每行信息将包含4个部分(字符串、整数、字符串、整数)。通过4个独立的编辑框和一个按钮,我将把这些信息添加到一个“数据库”(不确定我是否需要一个数据库,或者是否可以通过类似Tstringlist的东西来完成)。每次点击按钮时,它都会在“数据库”中添加当时键入的内容


保存数据的唯一要求是,当我从列表中键入第一个字符串时,它可以将属于它的其余信息也放在备忘录框或编辑框中。所以我想我必须能够搜索。只是想让它尽可能简单。只有大约10到15行信息。如果可能的话,我可以稍后再加载它们,这将是一件好事。

这里有一些非常基本的代码,可以帮助您顺利完成任务。没有错误检查,毫无疑问,您会希望进一步开发和修改它。关键是,应该有一些想法来帮助您编写适合您的代码

现在,我用逗号分隔了字段,但没有尝试处理任何值中逗号的外观。如果这是一个问题,请选择一个不同的分隔符,或转义逗号。我曾尝试过将每个字段写在自己的行上(有效地使用换行符作为分隔符),但这使得读取代码更难编写

同样,主要的一点是,这不是最终的生产代码,而是为您提供一个起点

function Split(const s: string; Separator: char): TStringDynArray;
var
  i, ItemIndex: Integer;
  len: Integer;
  SeparatorCount: Integer;
  Start: Integer;
begin
  len := Length(s);
  if len=0 then begin
    Result := nil;
    exit;
  end;

  SeparatorCount := 0;
  for i := 1 to len do begin
    if s[i]=Separator then begin
      inc(SeparatorCount);
    end;
  end;

  SetLength(Result, SeparatorCount+1);
  ItemIndex := 0;
  Start := 1;
  for i := 1 to len do begin
    if s[i]=Separator then begin
      Result[ItemIndex] := Copy(s, Start, i-Start);
      inc(ItemIndex);
      Start := i+1;
    end;
  end;
  Result[ItemIndex] := Copy(s, Start, len-Start+1);
end;

type
  TValue = record
    i1, i2: Integer;
    s: string;
  end;

  TMyDict = class(TDictionary<string,TValue>)
  public
    procedure SaveToFile(const FileName: string);
    procedure LoadFromFile(const FileName: string);
  end;

{ TMyDict }

procedure TMyDict.SaveToFile(const FileName: string);
var
  Strings: TStringList;
  Item: TPair<string,TValue>;
begin
  Strings := TStringList.Create;
  Try
    for Item in Self do begin
      Strings.Add(Format(
        '%s,%s,%d,%d',
        [Item.Key, Item.Value.s, Item.Value.i1, Item.Value.i2]
      ));
    end;
    Strings.SaveToFile(FileName);
  Finally
    FreeAndNil(Strings);
  End;
end;

procedure TMyDict.LoadFromFile(const FileName: string);
var
  Strings: TStringList;
  Item: TPair<string,TValue>;
  Line: string;
  Fields: TStringDynArray;
begin
  Strings := TStringList.Create;
  Try
    Strings.LoadFromFile(FileName);
    for Line in Strings do begin
      Fields := Split(Line, ',');
      Assert(Length(Fields)=4);
      Item.Key := Fields[0];
      Item.Value.s := Fields[1];
      Item.Value.i1 := StrToInt(Fields[2]);
      Item.Value.i2 := StrToInt(Fields[3]);
      Add(Item.Key, Item.Value);
    end;
  Finally
    FreeAndNil(Strings);
  End;
end;
函数拆分(常量s:string;分隔符:char):TStringDynArray;
变量
i、 ItemIndex:整数;
len:整数;
分隔计数:整数;
开始:整数;
开始
长度:=长度(s);
如果len=0,则开始
结果:=无;
出口
结束;
分离器计数:=0;
对于i:=1到len do begin
如果s[i]=分隔符,则开始
inc(分离计数);
结束;
结束;
设置长度(结果,分隔计数+1);
ItemIndex:=0;
开始:=1;
对于i:=1到len do begin
如果s[i]=分隔符,则开始
结果[ItemIndex]:=复制(s,开始,i-Start);
公司(项目索引);
开始:=i+1;
结束;
结束;
结果[项目索引]:=复制(s,开始,长度开始+1);
结束;
类型
t值=记录
i1,i2:整数;
s:字符串;
结束;
TMyDict=类别(t字典)
公众的
过程保存文件(常量文件名:字符串);
过程LoadFromFile(常量文件名:字符串);
结束;
{TMyDict}
过程TMyDict.SaveToFile(常量文件名:字符串);
变量
字符串:TStringList;
项目:TPair;
开始
字符串:=TStringList.Create;
尝试
对于Self do begin中的项目
Strings.Add(格式)(
“%s,%s,%d,%d”,
[Item.Key、Item.Value.s、Item.Value.i1、Item.Value.i2]
));
结束;
Strings.SaveToFile(文件名);
最后
FreeAndNil(字符串);
结束;
结束;
过程TMyDict.LoadFromFile(常量文件名:字符串);
变量
字符串:TStringList;
项目:TPair;
行:字符串;
字段:TStringDynArray;
开始
字符串:=TStringList.Create;
尝试
Strings.LoadFromFile(文件名);
对于字符串中的行,请不要开始
字段:=拆分(行“,”);
断言(长度(字段)=4);
Item.Key:=字段[0];
Item.Value.s:=字段[1];
Item.Value.i1:=stroint(字段[2]);
Item.Value.i2:=stroint(字段[3]);
添加(Item.Key、Item.Value);
结束;
最后
FreeAndNil(字符串);
结束;
结束;
请注意,您不会尝试搜索磁盘上的文件。您只需将其加载到内存、词典中,然后从那里查找内容

当你总是使用同一个键时,字典是很棒的。如果您有多个键,那么字典就不那么方便了,但是如果您只有15条记录,谁会关心性能影响呢


免责声明:我没有运行代码,也没有测试过代码等等。

正如我在上一个问题中告诉你的那样,这只是一本字典。那么,您对内存中的表示法感到满意吗?您只是在寻找如何读取和写入文件?@polyO60是否有可能将您的问题格式化为段落?这堵文本墙很难解析。你用两行新行写一段,既然这是一个个人项目,为什么不把所有的数据放在一个字符串列表中并保存到文件中呢?你真的不知道怎么做吗?数据库超过了15条记录的顶部@David Heffernan-是的,我对内存中的表示很满意,尤其是如果您可以通过从文件中加载和保存不同的表示来更改它。我使用Tdictionary的唯一问题是,我似乎无法找到如何将其设置为4列。有可能创建一个包含4列的stringlist并将其保存到文件中,打开它并在其中进行搜索。如果我在stringlist中有一行,上面有姓名、年龄、街道名称、门牌号。我能否只提供姓名,并找到其他信息?我不知道怎么做,我还没把它用上。为了尝试一下,我在一个表单上放了两个按钮。使用按钮1,我执行以下“项.键:=”hi';Item.Value.s:='bye';项目价值i1:=1;项目价值i2:=2;Strings.Add(item.Key);Strings.SaveToFile('test');'使用按钮2,我可以这样做:“Strings.LoadFromFile('hello');edit1.Text:=Item.key;edit2.Text:=Item.Value.s'当我按下按钮1,然后按下按钮2时,它工作。但是如果我关闭表单并再次打开它。然后只按按钮2。它不起作用。我做错了什么?@polyo60我不知道。当你提供的信息是“它不起作用”时,是不可能帮助你的。你必须开始具体点。但这听起来像是一个新问题,我们不能在评论中这样做。