关于freepascal:将记录从文本文件读取到Pascal中的数组中

Reading record from a text file into array in Pascal

1。这是我的代码,我想将文本文件中的记录读入pascal中的数组,我的程序是关于制作酒店帮手的,我已经有一个包含酒店数据的文本文件,那么我应该从中读取文本文件并将其存储在数组中..但我正面临错误103退出代码(文件未打开)....任何帮助的问题。 :)

程序Hotel1(输入,输出);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
const  max =10;  MaxFloor =10;
type
Date = record
        day :1..31;
        month:1..12;
        year:integer;
       end;


Booking = record
           Guest:string[20];
           S_Date:date;
           E_date:date;
          end;


Booking_Mat= array[1..max] of Booking;

History_Booking = record
                   B_num:integer;
                   B_Mat:Booking_Mat;
                  end;

Room = record
        Num:integer;
        Bed_num:integer;
        Price:integer;
        Status:Boolean;
        H:History_Booking;
       end;

Data = record
       Ro:Room;
       m:integer;
       end;

Data_mat= array [1..max] of Data;



Procedure  Read_Data(filename:string; var table:Data_mat);
 var   df:text; i,j :integer;
  n,m,num,GN:integer;
  Bed_num,Price:integer;
  f:text;
  s,e:Date;
  Gname:string[20];
  ok:boolean;
  a:Data_mat;
 c:char;
 Begin
 writeln('Reading ',filename,' records into array.... ');
 assign(df,filename);
 reset(df);
i:=0;
   while (not eof) do
     begin
        i:=i+1;
         Read (f,num);
         a[i].Ro.num:=num;
         Read (f,Bed_num);
         a[i].Ro.Bed_num:=Bed_num;
         Read (f,Price);
      a[i].Ro.Price:=Price;
         Read(f,c);
          if (c ='Y') then
           a[i].Ro.status:= true
       else
           a[i].Ro.status:= false;

      readln;

  End; {while eof}
  close(df);
End; {Read_Data}


您已经在var块中声明了两个类型为Text的变量(dff)。

使用以下几行打开df

1
2
assign(df,filename);
reset(df);

然后从f(不是您在上面打开的文件)中读取多行,例如:

1
Read (f, num);

有趣的是,即使您从未在循环中使用过它,您实际上也已经设法关闭了您真正打开的文件:

1
close(df);

所有这些问题的解决方案是删除fdf的声明,然后通过更正代码以使用其余的Text变量来解决编译器错误。 (这里有两个重要的课程是

  • 只声明您实际需要的变量。
  • 使用您声明的变量。
  • 您的循环也是无效的,因为您使用的是while not eof,没有提供可测试结束的文件。您的循环应改为while not Eof(df) do

    最好使用前缀类型T的典型命名约定。它清楚地表明它是类型而不是变量,并允许您更轻松地阅读代码。例如,我会将您的Data定义更改为TRoomData,并相应地更改其他类型声明。这是一个示例-请注意,TRoomData现在具有一个名为Room的字段(成员),其类型为TRoom

    1
    2
    3
    4
    TRoomData = record
      Room: TRoom;
      m: Integer;
    end;

    TRoom定义为

    1
    2
    3
    4
    5
    6
    7
    TRoom = record
      Num: Integer;
      Bed_num: Integer;
      Price: Integer;
      Status: Boolean;
      H: THistory_Booking;
    end;

    等等。这使您可以更清晰地编写代码:

    1
    2
    3
    4
    5
    6
    7
    var
      RoomData: TRoomData;
    begin
      RoomData.Room.Num := 1;
      RoomData.Room.Price := 50;
      // etc.
    end;

    话虽如此,您的文件不包含Text,因此首先使用df: Text来使用错误的文件类型。您应该使用File of TRoomData,以允许您一次读取和写入整个记录。这是一个这样做的例子:

    1
    2
    3
    4
    5
    6
    7
    var
      DF: File of TRoomData;
      RoomData: TRoomData;
      i: Integer;
    const
      DataFileName = 'D:\\TempFiles\
    oomData.dat'
    ;

    撰写:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // Put some data into the record
    RoomData.Room.Num := 1;
    RoomData.Room.Bed_num := 1;
    RoomData.Room.Price := 40;
    RoomData.Room.Status := True;
    RoomData.Room.H.B_num := 1;
    for i := 1 to Max do
    begin
      RoomData.Room.H.B_Mat[1].Guest := Format('Guest %d', [i]);
      RoomData.Room.H.B_Mat[1].S_Date.Year := 2014;
      RoomData.Ro.H.B_Mat[1].S_Date.Month := i;
      RoomData.Ro.H.B_Mat[1].S_Date.Day := i;
    end;

    // Write it out to the file
    AssignFile(DF, DataFileName);
    try
      Rewrite(DF);
      Write(DF, RoomData);
    finally
      CloseFile(DF);
    end;

    以以下方式读回:

    1
    2
    3
    4
    5
    6
    7
    AssignFile(DF, DataFileName);
    try
      Reset(DF);
      Read(DF, RoomData);
    finally
      CloseFile(DF);
    end;

    (或者,更好的是:如果您使用的Pascal版本支持它,请远离旧的文件I / O例程,而开始使用TFileStream。)

    最后但并非最不重要的一点,就是学习正确格式化代码。它使调试和维护变得更加容易,并且当您可以清楚地遵循执行路径时,它也使阅读变得更加容易。