Page 1 of 1

help with searching and files

Posted: Thu Apr 10, 2003 8:17 am
by Zymatic
I am writing a program for computer science class and the guide lines require it have different features.  I alreayd posted about help on the sorting part of it now I need help with searching the database created by the program.  Everything is stored in random files.  I don't have the code from the actual program to include but I wrote a quick test snippit that shows the basic idea of how it is coded in my program. I will try to get a snippit of the ral code to further help you with helping me.  The problem I'm having is when it compares the different variables for the search it doesn't seem to find that they are the same.  when I printed out the variables seperately the were infact the same but the program just prints out my ELSE part or my IF statement.  any help or comments or suggestions would be greatly appricated!  Code is below. ( none of it is commented or even tabbed in or spaced correctly because it is just a quick bit I wrote for this post)

Code: Select all

TYPE testRecord
test AS STRING * 20
END TYPE


DIM test AS testRecord
DIM test2$(1 TO 4)

OPEN "test.dat" FOR RANDOM AS #1 LEN = LEN(test)


FOR x = 1 TO 4
READ test.test
PUT #1, x, test
NEXT x

FOR y = 1 TO 4
GET #1, x, test
test2$(x) = test.test
NEXT y

INPUT "search for"; target$
FOR y = 1 TO 4

       IF target$ = test2$(y) THEN
         PRINT target$

       ELSE

       END IF
   NEXT y
FOR y = 1 TO 4
PRINT test2$(y)
NEXT y
DATA aaaa, bbbb, cccc, dddd
CLOSE

END

thanks,

Zymatic

Re: help with searching and files

Posted: Sat Apr 12, 2003 8:19 am
by Dr_Davenstein
I noticed that you used the syntax "STRING  * 20".
You might try to incorporate Rtrim$ into your code or you might try to use the exact same TYPE definition for both variables.


TYPE testRecord
test AS STRING * 20
END TYPE


DIM test AS testRecord


'DIM test2$(1 TO 4)
Instead of that...

:' Try this for instance.
DIM test2$(1 TO 4) as testrecord

Re: help with searching and files

Posted: Sat Apr 12, 2003 8:22 am
by Zymatic
OK, thanks for your suggestion, I'll try changing the DIM statement and see if it helps!  I'm not familiar with the Rtrim$ statement, could you explain it to me, or atleast give a brief description of what it does? Thanks for your help!

Zymatic

Re: help with searching and files

Posted: Tue Apr 15, 2003 4:23 am
by Zymatic
Still having trouble with this little problem, and since the code I posted wasn't code from my actual program and it would be harder for you guys to help me out completely I've decided to upload my whole program .bas file.  if you could take the time to look at it and help that'd be great!  program written in qbasic 1.1.

http://www.angelfire.com/ex/tempsite/ch10test.bas

thanks

Zymatic

Re: help with searching and files

Posted: Tue Apr 15, 2003 4:35 am
by Baz
HI
Sorry that link does not work for me  :-/

Yes, post your code here...

Posted: Tue Apr 15, 2003 12:35 pm
by Guest
'man what a mess!!
'here's the fixed up version.
'You should realy post your code...no
'telling what else is could be a problem.
'--MiggyD (@ qbcafe')
'***NOTE your problem code is REM'd out

'TYPE testRecord
'test AS STRING * 20
'END TYPE
'--fixed--not proper programming:unintelligible variables
TYPE RecordStructure
   SomeStr AS STRING * 20
END TYPE


'DIM test AS testRecord
'DIM test2$(1 TO 4)
'--fixed--unintelligible variables
DIM MagicWord AS RecordStructure
DIM ComparisonArray$(1 TO 4)


'OPEN "test.dat" FOR RANDOM AS #1 LEN = LEN(test)
'--fixed--pretty much OK but I've changed the ARRAY's Name
OPEN "Test.DAT" FOR RANDOM AS #1 LEN = LEN(MagicWord)


'FOR x = 1 TO 4
'READ test.test
'PUT #1, x, test
'NEXT x
'--fixed--What's up with the X in 'PUT #1' ?
FOR x = 1 TO 4
   READ MagicWord.SomeStr
   PUT #1, , MagicWord.SomeStr
NEXT x


'--fixed--you didn't reset the pointer
SEEK #1, 1


'FOR Y = 1 TO 4
'GET #1, x, test
'test2$(x) = test.test
'NEXT Y
'--fixed--You are using 'Y' in the FOR/NEXT, yet
'         storing with an 'X'; what's up with the 'X'
'         in 'GET #1' ?

FOR Y = 1 TO 4
   GET #1, , MagicWord.SomeStr
   ComparisonArray$(Y) = RTRIM$(MagicWord.SomeStr)
NEXT Y


'--fixed--moved CLOSE to avoid thrashing of disk; also
'         we no longer need the file opened (for the rest
'         of the program.)

CLOSE


'INPUT "search for"; target$
'--fixed--added CLS; also changed INPUT prompt so
'         users know what data is requested.

CLS
INPUT "Enter String To Search For: "; target$


'FOR Y = 1 TO 4
'  IF target$ = test2$(Y) THEN
'    PRINT target$
'  ELSE
'  END IF
'   NEXT Y
'--fixed--Changed due to ARRAY re-naming; also
'         better output of information and data

FOR Y = 1 TO 4
   IF target$ = ComparisonArray$(Y) THEN
       PRINT
       PRINT "Match Found in #"; LTRIM$(STR$(Y))
       PRINT "Target: "; target$
       PRINT "Array : "; ComparisonArray$(Y)
       PRINT
   END IF
NEXT Y


'FOR Y = 1 TO 4
'PRINT test2$(Y)
'NEXT Y
'--fixed--due to ARRAY re-naming
FOR Y = 1 TO 4
   PRINT ComparisonArray$(Y)
NEXT Y


'--not fixed--this is fine the way it is
DATA aaaa, bbbb, cccc, dddd


'--fixed--moved CLOSE to avoid thrashing of disk;
'         see above.

'CLOSE


'--not fixed--this is fine the way it is
END

-----------------------------
Three of your major problems with this was:

you used 'X' to PUT and GET.
you used 'Y' to GET (x).
you didn't reset file pointer to beginning of file.

Let us know if this has helped or not.  ALSO, you should really post all your code incase there are any other potential problems that you have not come across yet.

--MiggyD

Pardon me

Posted: Tue Apr 15, 2003 12:48 pm
by Guest
Sorry about the "what a mess" statement, I just re-read your first post (carefully this time) and you did state that it was not the actual code but a facsimile.  You should throw eggs on my face.

The reason for this second post was to amend one of the "--fixed--" notes I mentioned above.  In particulare:

Code: Select all

'FOR Y = 1 TO 4 
'  IF target$ = test2$(Y) THEN 
'    PRINT target$ 
'  ELSE 
'  END IF 
'   NEXT Y 
'--fixed--Changed due to ARRAY re-naming; also 
'    better output of information and data 
FOR Y = 1 TO 4 
    IF target$ = ComparisonArray$(Y) THEN 
   PRINT 
   PRINT "Match Found in #"; LTRIM$(STR$(Y)) 
   PRINT "Target: "; target$ 
   PRINT "Array : "; ComparisonArray$(Y) 
   PRINT 
    END IF 
NEXT Y 
It should have been:

'--fixed--Changed due to ARRAY re-naming; better
'    output of information and data; also nothing to
'    do in the ELSE section so it was removed.


--MiggyD

Re: help with searching and files

Posted: Wed Apr 16, 2003 12:56 am
by Zymatic
I don't mind that you read it wrong and posted that stuff mistakes happen.  anyway the reason why I didn't post my actual program code is it is quite long and I just figured it would be easier to allow you guys to download my .bas file and look at it that way so you can see all the different parts.  

also you mentioned about proper programming and resetting pointers and such,  if things like that are in my programming it is because I am just doing it the way my highschool computer science teacher taught it/wants it.  and the pointers thing he never even taught us about those so thats why I didn't use it.   I'll try to fix the link and if that doesn't work I'll post just my search section from my program.

Zymatic

Re: help with searching and files

Posted: Wed Apr 16, 2003 1:09 am
by Zymatic
ok so I can't get the link to work so here is the code for my sequential search.  you'll probably find a bunch of improper programming techniques but I'm not as concerned with that (unless it fixes my problem) as i am with trying to get the search to work! alot of things are REM'd out as well becaue they were stuff I added to see if the variables actually had data etc.. or just me trying different methods of getting it to work.

Code: Select all

SUB bandsearchseq (cd AS CDRecord, band$(), title$(), year(), genre$())
'*** this sub uses a sequential to search for a user specified band ***
CLS
'*** asks for band name ot search for ***
INPUT "Enter band name to search for"; target$
target$ = UCASE$(target$)



' ***** puts info from file into arrays ******
FOR a = 1 TO LOF(1) / LEN(cd)
    GET #1, a, cd
    band$(a) = cd.band
    title$(a) = cd.title
    year(a) = cd.year
    genre$(a) = cd.genre
NEXT a




' *** searches each record and if target is found outputs it ***
 FOR a = 1 TO LOF(1) / LEN(cd)
     PRINT band$(a)
 &nbsp; &nbsp; IF target$ <> band$(a) THEN
 &nbsp; &nbsp; &nbsp; &nbsp; PRINT "Band not found. Please try again."
 &nbsp; &nbsp; ELSE
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT " Band Name: &nbsp; "; band$(a)
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT " &nbsp;Cd Title: &nbsp; "; title$(a)
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT " &nbsp; &nbsp; &nbsp;year: &nbsp;"; year(a)
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT " &nbsp; &nbsp; genre: &nbsp; "; genre$(a)
 &nbsp; &nbsp; END IF
 NEXT a
 &nbsp; &nbsp; &nbsp; &nbsp;b = 1
 &nbsp; &nbsp; &nbsp; &nbsp;DO WHILE b = 1
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INPUT "Return to main menu (y/n)"; choice$
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; choice$ = UCASE$(choice$) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' make choice$ upper case
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IF choice$ = "Y" THEN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' if choice is Y then
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b = 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;' call menu sub
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CALL menu(cd, band$(), title$(), year(), genre$())
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSEIF choice$ = "N" THEN
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b = 0
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Thank You. GoodBye." &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' else end program
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSEIF choice$ <> "Y" AND choice$ <> "N" THEN
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Invalid choice"
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b = 1
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END IF
 &nbsp; &nbsp; &nbsp; LOOP

END SUB
thanks again for any help!

Zymatic

Re: help with searching and files

Posted: Thu Apr 17, 2003 4:14 am
by John_Schofield
Hi

What I think I'd do here (without wanting to change your code too much) would be as follows:

1) ' ***** puts info from file into arrays ******

I'd ignore this bit of code until you find the right record - you're just slowing down the searching.


2) foundrec%=0: rem set marker for found record
&nbsp; &nbsp;FOR a = 1 TO LOF(1) / LEN(cd)
&nbsp; &nbsp; GET 1, a
&nbsp; &nbsp; if ucase$(ltrim$(rtrim$(target$)))=ucase$(ltrim$(rtrim$(band$))) then
&nbsp; &nbsp;rem - this strips off all spaces both at the start and at the end of the two strings and makes sure you're checking same case state
&nbsp; rem load the elements from the file as record found
&nbsp; foundrec%=1:exit for
&nbsp;NEXT a
&nbsp;if foundrec%=0 then
&nbsp; rem do not found the record routine
&nbsp;else
&nbsp; rem do found record routine (load elements and display)
....rest of program


What you should also consider is using the instr function so that you can search on part of a band's name.

You seem to be mixing up different types of variables which is probably confusing your program. Try just sticking to strings for the random file where you can and this means you can just do string compares until you get the right answer. The idea of using ltrim$ and rtrim$ means that only the relevant part of the string (i.e. the actual name) is checked

There's still some further work to be done here and I'll look at it some more if you like when I have time.

regards

John

Re: help with searching and files

Posted: Thu Apr 17, 2003 4:17 am
by John_Schofield
previous reply was a bit messy on the loops because of the tiny window for the reply - I lost track of where I was. Of course, there should be an END IF statement atfter the "foundrec%=1:exit for" line

You're in a whirl of hurt

Posted: Thu Apr 17, 2003 7:05 am
by Guest
Are you sure you can't paste the entire code? &nbsp;Reason is that this Sub alone doesn't help. &nbsp;We need to see the global variables from the main mod and how the CALLing is being done.

Right off the top, I see a (potentially) major problem with recursing in your last DO/LOOP--if it hasn't happened yet. &nbsp;You'll probably get it to work 15 or 16 times before the program crashes.

I'll check your code later, but it seems to need some VERY major changes. &nbsp;And, since you can't paste the entire code, I'll have to make some presumptions and that's not good.

In the meantime, you can check out the following which is a modification to the one I posted on Apr 15. &nbsp;I've add the SUBs so that you can compare what you have to how it might be in order for your code to function properly.

Code: Select all

'--This is in main module
'--you can better see this when you use
'--QB to view it.
'--MiggyD
'
TYPE RecordStructure
 &nbsp; &nbsp;SomeStr AS STRING * 20
 &nbsp; &nbsp;SomeTime AS DOUBLE
END TYPE

DECLARE SUB SaveArray ()
DECLARE SUB ReadArray ()

DIM SHARED MagicWord AS RecordStructure
DIM SHARED ComparisonArray(1 TO 4) AS RecordStructure
'DIM ComparisonArray$(1 TO 4)

OPEN "Test.tmp" FOR RANDOM AS #1 LEN = LEN(MagicWord)

CLS
PRINT "Saving data in 5 seconds...please wait"
CALL SaveArray

PRINT "Recording Data into an Array...please wait"
SLEEP 3
CALL ReadArray

CLOSE &nbsp; 'avoid thrashing

INPUT "Enter String To Search For: "; Target$
FOR Y = 1 TO 4
 &nbsp; &nbsp;IF Target$ = RTRIM$(ComparisonArray(Y).SomeStr) THEN
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Match Found in #"; LTRIM$(STR$(Y))
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Target: "; Target$
 &nbsp; &nbsp; &nbsp; &nbsp;'PRINT "Array : "; ComparisonArray$(Y)
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "SomeStr:"; ComparisonArray(Y).SomeStr
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "SomeTime:"; ComparisonArray(Y).SomeTime
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT
 &nbsp; &nbsp;END IF
NEXT Y

FOR Y = 1 TO 4
 &nbsp; &nbsp;'PRINT ComparisonArray$(Y)
 &nbsp; &nbsp;PRINT ComparisonArray(Y).SomeStr, STR$(ComparisonArray(Y).SomeTime)
NEXT Y
SLEEP 7

PRINT
INPUT "Want to see the actual data that is stored? (N/y)"; Target$
IF UCASE$(Target$) = "Y" THEN &nbsp;SHELL "TYPE Test.tmp"

DATA aaaa, bbbb, cccc, dddd

END


SUB ReadArray
 &nbsp; &nbsp;'--File is already opened from main module; therefore
 &nbsp; &nbsp;'--I need to tell the computer where the next READ FROM
 &nbsp; &nbsp;'--FILE position is supposed to be by using SEEK.
 &nbsp; &nbsp;SEEK #1, 1
 &nbsp; &nbsp;FOR Y = 1 TO 4
 &nbsp; &nbsp; &nbsp; &nbsp;GET #1, , MagicWord
 &nbsp; &nbsp; &nbsp; &nbsp;ComparisonArray(Y) = MagicWord
 &nbsp; &nbsp; &nbsp; &nbsp;'ComparisonArray$(Y) = RTRIM$(MagicWord.SomeStr)
 &nbsp; &nbsp;NEXT Y
END SUB


SUB SaveArray
 &nbsp; &nbsp;FOR x = 1 TO 4
 &nbsp; &nbsp; &nbsp; &nbsp;READ MagicWord.SomeStr
 &nbsp; &nbsp; &nbsp; &nbsp;MagicWord.SomeTime = TIMER
 &nbsp; &nbsp; &nbsp; &nbsp;PUT #1, , MagicWord
 &nbsp; &nbsp; &nbsp; &nbsp;SLEEP 1 &nbsp; &nbsp; 'to show MW.SomeTime is saving properly
 &nbsp; &nbsp;NEXT x
END SUB
HTH in the meantime.
--MiggyD

Yep, you may need a major overhaul

Posted: Thu Apr 17, 2003 1:18 pm
by Guest
It took me a while to fix it up so that I could even begin to use it and determin which variables you said you created for debugging purposes 'cause you didn't mention which ones and get rid of them. &nbsp;:'( &nbsp;

Anyway, here's my fix for your "sub"

Code: Select all

'-- I had to create some code in the
' &nbsp; Main Module for testing purposes.
' &nbsp; Therefore, I've not included them
' &nbsp; in this post. -- MiggyD @ QBCaf&#8218; Forum

DECLARE SUB BandSearchSeq ()
'$INCLUDE: 'MyTest.001'

SaveBandInfo
BandSearchSeq

CLOSE

END
'----------------------- End of Main Module -----------------------


SUB BandSearchSeq
'*************************************************
'*** Sequential search for user specified band ***
'*************************************************
'I will presume that you have the following in your Main Module:
'
' &nbsp; 1) a TYPE CDRecord coded.
' &nbsp; 2) a DIM SHARED CD AS CDRecord statement.
' &nbsp; 3) an OPEN filename FOR RANDOM AS 1 LEN = LEN(CDRecord) statment.
'

'--Local variable to count number of records that match.
Matches = 0

'--Get "BandName" from user to find
CLS
INPUT "Enter band name to search for"; Target$
Target$ = UCASE$(Target$)

'--Tell computer to start from the VERY beginning
'--of the OPENed file. ***Did you forget this?***
SEEK #1, 1

'--Sequential Search and Comparison Checking Routine/Code--
FOR RecNumber = 1 TO LOF(1) / LEN(CD)
 &nbsp; &nbsp;'--Get 1 record from the file
 &nbsp; &nbsp;GET #1, , CD
 &nbsp; &nbsp;'--Compare Target$ to data just retrieved from file
 &nbsp; &nbsp;IF Target$ = RTRIM$(UCASE$(CD.Band)) THEN
 &nbsp; &nbsp; &nbsp; &nbsp;'--Do this ONLY if a match is found
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Match Found at Record #"; STR$(RecNumber)
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT " &nbsp; &nbsp;Band Name: "; CD.Band
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT " &nbsp; CD's Title: "; CD.Title
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Year Released: "; CD.Year
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Style / Genre: "; CD.Genre
 &nbsp; &nbsp; &nbsp; &nbsp;Matches = Matches + 1
 &nbsp; &nbsp;END IF
NEXT RecNumber
 
'--Display number of matches
PRINT
PRINT "A total of"; STR$(Matches); " record(s) have been found."
PRINT

DO
 &nbsp; &nbsp;'--NOTE: You can re-use Target$ because we are all done
 &nbsp; &nbsp;'--using it for the SEARCHing task...so instead of eating
 &nbsp; &nbsp;'--up valuable 64k of DOS memory we'll re-use Target$ for
 &nbsp; &nbsp;'--this task instead of creating another variable called
 &nbsp; &nbsp;'--[CHOICE$]. OK?
 &nbsp; &nbsp;'
 &nbsp; &nbsp;'INPUT "Return to main menu (y/n)"; Target$
 &nbsp; &nbsp;INPUT "Search again? (y/n)"; Target$
 &nbsp; &nbsp;Target$ = UCASE$(Target$) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' make choice$ upper case

 &nbsp; &nbsp;'--Act on user's request
 &nbsp; &nbsp;IF Target$ = "Y" THEN
 &nbsp; &nbsp; &nbsp; &nbsp;'--User wants to continue, so exit DO/LOOP; and
 &nbsp; &nbsp; &nbsp; &nbsp;'--eventually this SUB.
 &nbsp; &nbsp; &nbsp; &nbsp;'
 &nbsp; &nbsp; &nbsp; &nbsp;EXIT DO
 &nbsp; &nbsp;ELSEIF Target$ = "N" THEN
 &nbsp; &nbsp; &nbsp; &nbsp;'--User wants to terminate program, so do it.
 &nbsp; &nbsp; &nbsp; &nbsp;'
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Thank You. GoodBye."
 &nbsp; &nbsp; &nbsp; &nbsp;END
 &nbsp; &nbsp;ELSE
 &nbsp; &nbsp; &nbsp; &nbsp;'--Key pressed was NOT a "Y" (see IF above)!
 &nbsp; &nbsp; &nbsp; &nbsp;'--Key pressed was NOT a "N" (see ELSEIF above)!
 &nbsp; &nbsp; &nbsp; &nbsp;'--Key pressed was something "else" (get it? "ELSE"? hehe)
 &nbsp; &nbsp; &nbsp; &nbsp;PRINT "Invalid Choice...Please re-enter": PRINT : SLEEP 2
 &nbsp; &nbsp;END IF
LOOP WHILE 0 = 0
END SUB
'--------------------------- End of Sub ---------------------------


SUB SaveBandInfo
 &nbsp; &nbsp;'$INCLUDE: 'MyTest.002'
END SUB
'--------------------------- End of Sub ---------------------------
Again, if you can, post the entire code for all to help you out.
--MiggyD