如何将此2d数组的内容保存到文件中

时间:2015-05-28 01:05:20

标签: delphi

我需要一些帮助,试图将2d数组的内容保存到文件中。 首先,我不确定该文件应该是什么类型等.txt或dat。

我已编辑帖子,以便代码采用文本格式而非图像。

这是我到目前为止所得到的。

program CaptureTheSarum;

{$APPTYPE CONSOLE}

uses
  SysUtils;

Const BoardDimension = 8;

Type
  TBoard = Array[1..BoardDimension, 1..BoardDimension] Of String;

Var
  Board : TBoard;
  GameOver : Boolean;
  StartSquare : Integer;
  FinishSquare : Integer;
  StartRank : Integer;
  StartFile : Integer;
  FinishRank : Integer;
  FinishFile : Integer;
  MoveIsLegal : Boolean;
  PlayAgain : Char;
  SampleGame : Char;
  WhoseTurn : Char;
  savedFile : text;

procedure InitialiseSave;
var
  fileName : string;
begin
  fileName := 'SavedGame.dat';

  assignfile(savedfile,fileName);
  if not fileexists(fileName)
  then
    begin
      rewrite(savedfile);
      closefile(savedfile)
    end
  {endif};
end;

procedure saveGame;
var
 save : string;
 RankNo,FileNo : integer;
begin
  writeln('Would you like to save the Game?');
  readln(save);

  if (save = 'y') or (save = 'Y')
  then
    begin
      reset(SavedFile);
      write(SavedFile,board[fileno,Rankno]);
      closeFile(SavedFile);
    end
  {endif};

3 个答案:

答案 0 :(得分:2)

要回答您的主要问题,您可以按如下方式保存二维字符串数组:

procedure TForm9.FileSaveClick(Sender: TObject);
var
  i, j: integer;
  fn: string;
  fs: TFileStream;
  fw: TWriter;
begin
  fn := 'c:\tmp\mychessfile.dat';
  fs := nil;
  fw := nil;
  try
    fs := TFileStream.Create(fn, fmCreate or fmShareDenyWrite);
    fw := TWriter.Create(fs, 1024);
    for i := 1 to BoardDimension do
      for j := 1 to BoardDimension do
        fw.WriteString(Board[i, j]);
  finally
    fw.Free;
    fs.Free;
  end;
end;

随后您可以使用以下命令将文件读回数组:

procedure TForm9.FileReadClick(Sender: TObject);
var
  i, j: integer;
  fn: string;
  fs: TFileStream;
  fr: TReader;
begin
  fn := 'c:\tmp\mychessfile.dat';
  fs := nil;
  fr := nil;
  try
    fs := TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite);
    fr := TReader.Create(fs, 1024);
    for i := 1 to BoardDimension do
      for j := 1 to BoardDimension do
          Board[i, j] := fr.ReadString;
  finally
    fr.Free;
    fs.Free;
  end;
end;

如您所见,我选择了通用.dat扩展名,因为该文件还包含二进制数据,如每个文本的长度,数据类型等。这些详细信息由TWriter /处理TReader课程。

您还应该考虑收到的有关文件结构选择的评论。 例如,谷歌搜索“国际象棋文件格式”(假设您正在进行国际象棋游戏),会显示Portable_Game_Notation和该页面的另一个参考:Forsyth-Edwards Notation

答案 1 :(得分:1)

看来你正试图制作某种棋盘游戏(可能是国际象棋)。

您面临的主要问题是您尚未将您的电路板类型定义为固定大小。您在Delphi中看到字符串具有动态大小。虽然在较旧版本的Delphi中,在较新版本中它们仅限于255个字符,但它们的大小仅受可用内存的限制。

因此,您应该将您的电路板定义(数组)更改为固定类型。对于大多数棋盘游戏,你可以使用二维数组Char。

TBoard = Array [0..7, 0..7] of Char;

在较旧的非Unicode版本的Delphi上,Char将是一个AnsiChar,它允许您存储256个不同的字符或256个不同的数字。

在支持Unicode的较新Delphi版本上,您有更多可能性。

无论如何,使用固定类型的静态数组最好的事情是你可以用一个命令将整个静态数组保存到一个文件中

procedure SaveGame;
//When having fixed size types you can use File of Type to quickly get
//ability to store whole type at once. 
//Note this only works for fixed sized records who don't contain any 
//dynamic sized members (strings, dynamic arrays) and static arrays of
//fixed sized type (no strings or other dynamic sized arrays)
//
//With arrays it doesn't even matter whether they are one dimensional 
//or multidimensional. but they need to be static
var Savefile: File of TBoard;
    FileName: String;
begin
  Filename := 'D:\Proba.txt';
  //Assign file
  Assignfile(Savefile,FileName);
  //Check if the file exists if it does open it for editing (reser)
  //else open it in rewrite mode which also automatically creates new 
  //file if the file doesn't exists
  if not Fileexists(Filename) then
    Rewrite(Savefile)
  else
    Reset(SaveFile);

  //Becouse we have a file of fixed sized type we can write the whole 
  //type with just one Write command 
  //your program already know how many bytes it has to write
  //
  //Note if you want to store multiple savegames in a single file you
  //need to use seek to move your current position
  //And because we have file of type the seek moves the current position
  //by N times of the type size
  //So if the size of your type is 64 bytes calling Seek(YourFile,2) 
  //will move current position to the 128th byte
  Write(SaveFile, Board);
  //Close file
  CloseFile(SaveFile);
end;

以类似的方式读取文件中的数据。

Read(Savefile, Board); 

编辑:如果您使用旧版本的Delphi并且char不允许您存储板单元状态的足够可能性,则可以像大多数其他基于网格的游戏一样使用整数数组。

答案 2 :(得分:0)

INI文件是这样的:

[d1]
1=element1
2=element2
...
[d2]
1=element1
...

但是,推荐XML,如下所示:

<array>
  <d1>
    <element1>value1</element1>
    <element2>value1</element2>
    ...
  </d1>
  <d2>
    <element1>value1</element1>
    ...
  </d2>
</array>