Reputation: 11
Im creating a program that displays a list of 10 books with the title, author and ISBN. The program can display the records and sort them but I am having trouble to searching for him. I do not know where to implement the FindArray identifier into the code and I don't know how to get the program to search for the Book. The records are stored in a .dat file. Any help would be appreciated. Here's the code:
uses SysUtils;
type TBook = Record
Number : integer;
Title : String[50];
Author : String[50];
ISBN : String[13];
end;
var Book : TBook;
CurrentFile : File Of TBook;
index : integer;
FindArray : array[1..10] of TBook;
Procedure Add_Book;
var Title, Author, ISBN : String;
index : integer;
begin
Assign (CurrentFile, 'C:\Books.dat');
reset (CurrentFile);
Seek (CurrentFile, filesize(CurrentFile));
Book.Number := (filepos(CurrentFile)+1);
writeln ('Type in book title');
readln (Title);
For index := 1 to Length(Title) do
Title[index] := Upcase(Title[index]);
Book.Title := Title;
writeln ('Type in author');
readln (Author);
For index := 1 to Length(Author) do
Author[index] := Upcase(Author[index]);
Book.Author := Author;
writeln ('Type in ISBN');
readln (ISBN);
For index := 1 to Length(ISBN) do
ISBN[index] := Upcase(ISBN[index]);
Book.ISBN := ISBN;
write (CurrentFile, Book);
Close (CurrentFile);
end;
Procedure Show_All;
begin
Assign (CurrentFile, 'C:\Books.dat');
reset (CurrentFile);
while filepos(CurrentFile) <> filesize(CurrentFile) do
begin
read (CurrentFile, Book);
writeln ('File: ', Book.Number);
writeln ('Title: ', Book.Title);
writeln ('Author: ', Book.Author);
writeln ('ISBN: ', Book.ISBN);
writeln;
end;
writeln;
write ('END OF FILE!');
readln;
Close (CurrentFile);
end;
Procedure Delete_All;
begin
Assign (CurrentFile, 'C:\Books.dat');
reset (CurrentFile);
seek (CurrentFile,0);
Truncate (CurrentFile);
Close (CurrentFile);
end;
Procedure Menu;
var option :integer;
begin
writeln ('Press appropriate number');
writeln;
writeln ('1. Search book');
writeln ('2. Quit');
readln (option);
CASE option of
1: show_all;
2: delete_all
else;menu
end; {End Case}
end;
begin
Assign (CurrentFile, 'C:\Books.dat');
reset (CurrentFile);
index := 0;
while not eof(CurrentFile) do
begin
index := index+1;
read (CurrentFile, Book);
end;
index := Book.Number;
repeat
menu
until eof(CurrentFile);
close (CurrentFile)
end.
This is my code so far. What do I have to do to make it search for the book title or the author?
Upvotes: 1
Views: 1205
Reputation: 84650
If I had a list of records that all used the same basic structure, and I wanted to be able to search through them and find records matching a certain filter pattern, the first thing I would do is put it into a SQL database instead of a file of [record type]
. Then I could simply run a query: select * from BOOKS where TITLE = :title
and let the DBMS handle the details.
If you can't do that, there are two basic ways to run your own filtering: by linear search, and by key lookup.
They both start the same way: read the entire file into memory, into an array of TBook. What you do next depends on your strategy.
Linear search is very simple:
function FindBookIndex(const searchTitle: string): integer;
begin
for i := 0 to high(bookArray) do
if bookArray[i].Title = searchTitle then
exit(i);
result := -1; //not found
end;
Indexed search takes a bit more work up-front, but is a lot faster to actually run the search. You set up a TDictionary
mapping strings (titles) to integers (array indices). Then to run a lookup, call TryGetValue
on the dictionary, and return -1 if there's no result. Note that this will only work on exact matches; if you want to do a partial match (books where the title contains the word "Wind," for example,) you either need a linear search or a much more sophisitcated indexing scheme.
But again, really the simplest way to do this is to put it in a database.
Upvotes: 1