Author Topic: search txt file for a certain number  (Read 3999 times)

0 Members and 1 Guest are viewing this topic.

Offline durgensrun

  • Newbie
  • Posts: 7
  • Man of many talents
    • View Profile
search txt file for a certain number
« on: October 26, 2020, 09:24:13 pm »
I am trying to search a text file for data. Each data line has 10 items. the first data item is a 6 digit id number.
I input an id number to search for, then print all 10 items on the screen on that line. I think I am missing something.
thanks

Code: QB64: [Select]
  1. TYPE ContactType 'there are 10 items in the text file
  2.     idnum AS STRING * 6
  3.     consumerid AS STRING * 6
  4.     firstname AS STRING * 20
  5.     lastname AS STRING * 20
  6.     address1 AS STRING * 25
  7.     address2 AS STRING * 25
  8.     city AS STRING * 20
  9.     state AS STRING * 2
  10.     zip AS STRING * 5
  11.     phone AS STRING * 10
  12.     email AS STRING * 25
  13. DIM consumer AS ContactType
  14.  
  15. LOCATE 5, 30: INPUT "consumerid: ", idnum
  16. OPEN "durgenDB/contactlist.txt" FOR BINARY AS #1
  17. a$ = SPACE$(LOF(1))
  18. GET #1, 1, a$
  19.  
  20. foundError = INSTR(a$, "idnum")
  21. IF foundidnum THEN
  22.  
  23.     DO
  24.         PRINT consumer.consumerid, consumer.firstname, consumer.lastname, consumer.address1, consumer.address2, consumer.city, consumer.state, consumer.zip, consumer.phone, consumer.email
  25.         foundidnum = INSTR(foundidnum + 1, a$, "idnum")
  26.     LOOP WHILE foundidnum > 0

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: search txt file for a certain number
« Reply #1 on: October 26, 2020, 09:27:22 pm »
If I were you I'd do a DO, LINE INPUT, LOOP rather than getting it all at once. That way you can stop once you find the value you are looking for.
Shuwatch!

Offline durgensrun

  • Newbie
  • Posts: 7
  • Man of many talents
    • View Profile
Re: search txt file for a certain number
« Reply #2 on: October 26, 2020, 10:00:11 pm »
this is what's in the text file, the data in it is only temporary for testing.

Quote
"123456","ZEF                 ","DURGEN              ","MOUNT                ","                         ","REYNO               ","AR","12345","0123456789","moo@zap.com              "
"098765","BOB                 ","MOLE                ","KIM DR                   ","                         ","BIGGERS             ","AR","65432","1234567890","bee@mook.com             "

the first numbers, a 6 digit number, is the unique identifier for that line of data.
what I need to do is search the text file for that unique number, and print all data items on the screen on that line only.
thanks

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: search txt file for a certain number
« Reply #3 on: October 26, 2020, 10:09:46 pm »
OMG you set up a record to a data file!

You can make an array of these records, your user defined type, and access each field of each index item of an array of records.

Code: QB64: [Select]
  1. TYPE ContactType 'there are 10 items in the text file <<< VVV these are fields of a record with Random access
  2.     idnum AS STRING * 6
  3.     consumerid AS STRING * 6
  4.     firstname AS STRING * 20
  5.     lastname AS STRING * 20
  6.     address1 AS STRING * 25
  7.     address2 AS STRING * 25
  8.     city AS STRING * 20
  9.     state AS STRING * 2
  10.     zip AS STRING * 5
  11.     phone AS STRING * 10
  12.     email AS STRING * 25
  13. DIM consumer AS ContactType  ' a record
  14.  
  15. LOCATE 5, 30: INPUT "consumerid: ", idnum
  16. OPEN "durgenDB/contactlist.txt" FOR RANDOM AS #1 LEN = LEN(consumer)
  17.     recNumber = recNumber + 1
  18.     GET #1, recNumber, consumer
  19.     IF VAL(consumer.idnum) = idnum THEN ' found!
  20.         'print consumer.this and that as needed
  21.  
  22.          EXIT WHILE
  23.     END IF
  24.  

I am rusty with Random access but this might work.

EDITS: sorry still fixing typos

You can also input the idnum as a string instead of a number might be better for matching.
« Last Edit: October 26, 2020, 10:16:07 pm by bplus »

Offline durgensrun

  • Newbie
  • Posts: 7
  • Man of many talents
    • View Profile
Re: search txt file for a certain number
« Reply #4 on: October 26, 2020, 10:24:34 pm »
bplus, I am getting error 52 on line 19, "WHILE NOT EOF(1)"
thanks

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: search txt file for a certain number
« Reply #5 on: October 26, 2020, 10:32:22 pm »
Hi @durgensrun

Did you make all your strings as long as spec'd in the Type? If any one is one byte short you won't load a single record.

Yeah also we should count number of records in file first by taking LOF(1) and dividing by record len and exit if we try to go get a record past the last record number.


Quote
"123456","ZEF                 ","DURGEN              ","MOUNT                ","                         ","REYNO               ","AR","12345","0123456789","moo@zap.com              "
"098765","BOB                 ","MOLE                ","KIM DR                   ","                         ","BIGGERS             ","AR","65432","1234567890","bee@mook.com             "

Yeah a Random Access file is not full of commas and double quotes between fields.
« Last Edit: October 26, 2020, 10:39:17 pm by bplus »

Offline durgensrun

  • Newbie
  • Posts: 7
  • Man of many talents
    • View Profile
Re: search txt file for a certain number
« Reply #6 on: October 26, 2020, 10:55:30 pm »
Hi bplus
It's been 30 years since I made my first program, I am relearning with a special project. I am making a small relational 3-page database.
the text file I posted will hold all the names and addresses and would be added to, so I don't know how many lines will be on it, same with the other 2 text files.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: search txt file for a certain number
« Reply #7 on: October 26, 2020, 11:14:12 pm »
Do you know or is it remember about filling fixed string fields for a record?

Wait have you worked with Random Access?

Your file looks like CVS style data lines.

Offline durgensrun

  • Newbie
  • Posts: 7
  • Man of many talents
    • View Profile
Re: search txt file for a certain number
« Reply #8 on: October 26, 2020, 11:15:03 pm »
Long ago I did.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: search txt file for a certain number
« Reply #9 on: October 26, 2020, 11:17:56 pm »
Yeah what you have is more CVS style except you don't need spaces for that.

A random access file would not have quotes or commas but allot of spaces! specially with fixed strings.

Random access you'd want to make numbers as much as possible at the smallest Type size that would fit your data range.
« Last Edit: October 26, 2020, 11:20:01 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: search txt file for a certain number
« Reply #10 on: October 27, 2020, 12:23:59 am »
@durgensrun

Did you see this I made for badger for data entry for multiple fields to create / edit a record?
Code: QB64: [Select]
  1. TYPE customer
  2.     id AS LONG
  3.     first AS STRING * 25
  4.     last AS STRING * 25
  5.     address AS STRING * 30
  6.     city AS STRING * 25
  7.     state AS STRING * 2
  8.     zip AS STRING * 5
  9.     phone AS STRING * 10
  10.  
  11. DIM SHARED nRecs ' for when you get a file going
  12.  
  13.  
  14. DIM myRec AS customer 'edit this record over and over for testing
  15.     edit = EditCustomer(myRec, 1) ' assign to first record 1 if not Cancelled
  16.     CLS
  17.     IF edit THEN
  18.         PRINT "Record #:"; myRec.id
  19.         PRINT "   First:"; myRec.first
  20.         PRINT "    Last:"; myRec.last
  21.         PRINT " Address:"; myRec.address
  22.         PRINT "    City:"; myRec.city
  23.         PRINT "   State:"; myRec.state
  24.         PRINT "   Phone:"; myRec.phone
  25.     ELSE
  26.         PRINT "user cancelled edit"
  27.     END IF
  28.     PRINT "(SLEEPing) press any to continue..."
  29.     SLEEP
  30.     CLS
  31. 'if edit then fileRec myRec, 1
  32.  
  33. 'return 0 if user cancelled, -1 if record edit was accepted
  34. FUNCTION EditCustomer% (customerRec AS customer, recNumber AS LONG) ' use for new Customer or edit Customer
  35.     DIM rec(1 TO 7, 0 TO 1) AS STRING
  36.     rec(1, 0) = "First Name"
  37.     rec(2, 0) = "Last Name"
  38.     rec(3, 0) = "Address"
  39.     rec(4, 0) = "City"
  40.     rec(5, 0) = "State (abbrev:2)"
  41.     rec(6, 0) = "Zip (5)"
  42.     rec(7, 0) = "Phone" ' might split to Home and Mobile
  43.     IF customerRec.first <> "" THEN rec(1, 1) = customerRec.first
  44.     IF customerRec.last <> "" THEN rec(2, 1) = customerRec.last
  45.     IF customerRec.address <> "" THEN rec(3, 1) = customerRec.address
  46.     IF customerRec.city <> "" THEN rec(4, 1) = customerRec.city
  47.     IF customerRec.state <> "" THEN rec(5, 1) = customerRec.state
  48.     IF customerRec.zip <> "" THEN rec(6, 1) = customerRec.zip
  49.     IF customerRec.phone <> "" THEN rec(7, 1) = customerRec.phone
  50.     doAgain:
  51.     CLS
  52.     FOR i = 1 TO 7 'show what we have
  53.         PRINT i, rec(i, 0); " = "; rec(i, 1)
  54.     NEXT
  55.     PRINT: PRINT "Press a to Accept, n for New, a digit to edit field, or escape to Cancel."
  56.     choice$ = getChar$("aAnN1234567" + CHR$(27))
  57.     IF ASC(choice$) = 27 THEN ' maybe this should be a function
  58.         EditCustomer% = 0: EXIT FUNCTION 'cancelled  EDIT to 0
  59.     ELSEIF UCASE$(choice$) = "A" THEN
  60.         customerRec.id = recNumber 'assign the record
  61.         customerRec.first = rec(1, 1)
  62.         customerRec.last = rec(2, 1)
  63.         customerRec.address = rec(3, 1)
  64.         customerRec.city = rec(4, 1)
  65.         customerRec.state = rec(5, 1)
  66.         customerRec.zip = rec(6, 1)
  67.         customerRec.phone = rec(7, 1)
  68.         EditCustomer% = -1: EXIT FUNCTION 'done
  69.     ELSEIF UCASE$(choice$) = "N" THEN
  70.         CLS
  71.         FOR i = 1 TO 7
  72.             PRINT rec(i, 0); " > ";
  73.             INPUT ""; rec(i, 1)
  74.         NEXT
  75.         GOTO doAgain
  76.     ELSEIF INSTR("1234567", choice$) THEN
  77.         CLS
  78.         PRINT rec(VAL(choice$), 0); " > ";
  79.         INPUT ""; rec(VAL(choice$), 1)
  80.         GOTO doAgain
  81.     END IF
  82.  
  83. FUNCTION getChar$ (fromStr$) ' get a char$ usually for a menu
  84.     DIM OK AS INTEGER, k$
  85.     WHILE OK = 0
  86.         k$ = INKEY$
  87.         IF LEN(k$) THEN
  88.             IF INSTR(fromStr$, k$) <> 0 THEN OK = -1
  89.         END IF
  90.         _LIMIT 200
  91.     WEND
  92.     _KEYCLEAR
  93.     getChar$ = k$
  94.  
  95.  

Modify it for your type and half the work of data entry is done! :)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: search txt file for a certain number
« Reply #11 on: October 27, 2020, 02:05:19 am »
Question:  If this ID is unique, and doesn’t appear anywhere else, can’t you just:

OPEN file$ FOR BINARY AS #1
l = LOF(1)
temp$ = SPACE$(l)
GET #1, 1, temp$
CLOSE

p = INSTR(temp$, id$)
IF p <> 0 THEN ... you found your record at position p

EDIT: Since the ID is *always* in the starting position of your record, you can even error check to rule out false positives with a position check:
IF p MOD LEN(record_type) = 1 THEN .... it’s valid......  ELSE....  it’s in an address, or such and not in the proper position to be an ID field

« Last Edit: October 27, 2020, 02:09:17 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: search txt file for a certain number
« Reply #12 on: October 27, 2020, 11:16:32 am »
If you were going Random Access route the customer ID would be same as record number, so you just GET record # of customer. Random Access depends upon records and fields of a record being exactly the same size so lots of empty spaces for all strings records/fields.

But I think you might like variable length fields and Steve had start of that somewhere, ah here:
https://www.qb64.org/forum/index.php?topic=3076.msg123525#msg123525
Steves method depends on keeping another file to record lengths of each and every field.

Another approach with variable length depends on using delimiters for records and another for fields in record. Use Split as parser, use of CHR$(10) would be good to separate records (called delimiter) and another character to delimit the fields (each item in your customer Type). You'd first SPLIT the file into records array and then each record split again by another delimiter (maybe comma or semi colon or colon?) and ideally your fields would be in same order.

Split1000 very powerful and handy parser: https://www.qb64.org/forum/index.php?topic=1607.0

And still your customer ID number could be same as record number = array index after split files into records for fast lookup of a customer.

sample file: fields comma delimited and records chr$(10) delimited:
fileStr$ = "1,ZEF,DURGEN,MOUNT, ,REYNO,AR,12345,0123456789,moo@zap.com" + chr$(10) +
"2,BOB,MOLE,KIM DR, ,BIGGERS,AR,65432,1234567890,bee@mook.com" + chr$(10) + ... 
customer ID = same as record #

in an editor chr$(10) is same as next line, so piece of cake to write the file in a standard text editor (no double quotes each line is record.)

Also with variable length strings you don't have to use TYPE with fixed strings but TYPE might be used with variable strings to keep better organized and labeled specially with 11 fields. Just have to JOIN fields to make a record and JOIN records to make a single giant string to store back as file. JOIN is opposite of split building strings with commas between each field the building file string with CHR$(10) between each record.

RANDOM ACCESS doesn't need the splits and joins nor another file to track lengths of ever individual field, it just uses allot empty space to ensure each field from Type is same size so records are same size so you can GET or PUT records a chunk at a time.
« Last Edit: October 27, 2020, 12:06:36 pm by bplus »

Offline durgensrun

  • Newbie
  • Posts: 7
  • Man of many talents
    • View Profile
Re: search txt file for a certain number
« Reply #13 on: October 27, 2020, 11:24:12 pm »
I been working on the problem. This is what I have so far. "sub finder" scans the file, when it finds a match it stops and says found it.
"Sub display", reads the 10 variables in the line, and prints them to the screen. The "IDnumber" is always the first variable in the set of 10.
The next problem is how to combine the 2 subs. The sequence I need is, I input an "IDnumber" to search for. Then scans the file. When that number is found.
The program goes and reads in the 10 variables including the "IDnumber" found on that line and prints them on screen.

I am thinking if I count the variables during the search this would give me an address of sorts, then rescan the file counting the variables and stoping the scan -1 prior to the found variable.
Then load in the next 10 variables I need to print.

Code: QB64: [Select]
  1. SUB finder
  2.     CLS
  3.     OPEN "durgenDB/consumerprofile.dat" FOR INPUT AS #1
  4.     INPUT " Profile number to find  ", searchnumber
  5.  
  6.     DO UNTIL EOF(1)
  7.         INPUT #1, IDnumber
  8.         PRINT IDnumber
  9.         IF IDnumber = searchnumber THEN PRINT "found it   ": END
  10.     LOOP
  11.     CLOSE #1
  12.  
  13. SUB display
  14.     OPEN "durgenDB/consumerprofile.dat" FOR INPUT AS #1
  15.     INPUT #1, IDnumber
  16.     INPUT #1, FirstName$
  17.     INPUT #1, LastName$
  18.     INPUT #1, Address1$
  19.     INPUT #1, Address2$
  20.     INPUT #1, City$
  21.     INPUT #1, State$
  22.     INPUT #1, Zip$
  23.     INPUT #1, Phone$
  24.     INPUT #1, Email$
  25.     CLOSE #1
  26.  
  27.     LOCATE 2, 10: PRINT "Costumer Profile": PRINT "-----------------------------------------------------------------"
  28.     LOCATE 4, 10: PRINT "Consumer No.: ": LOCATE 4, 22: PRINT IDnumber
  29.     LOCATE 6, 10: PRINT "Name: ": LOCATE 6, 16: PRINT RTRIM$(FirstName$); " "; RTRIM$(LastName$)
  30.     LOCATE 8, 10: PRINT "Mailing Address: ": LOCATE 8, 27: PRINT RTRIM$(Address1$)
  31.     LOCATE 10, 10: PRINT "Shipping Address: ": LOCATE 10, 28: PRINT "bloop" 'RTRIM$(Adress2$)
  32.     LOCATE 12, 10: PRINT "City: ": LOCATE 12, 16: PRINT City$
  33.     LOCATE 14, 10: PRINT "State: ": LOCATE 14, 17: PRINT State$
  34.     LOCATE 16, 10: PRINT "Zip: ": LOCATE 16, 15: PRINT Zip$
  35.     LOCATE 18, 10: PRINT "Phone: ": LOCATE 18, 17: PRINT Phone$
  36.     LOCATE 20, 10: PRINT "E-Mail: ": LOCATE 20, 18: PRINT Email$

Offline durgensrun

  • Newbie
  • Posts: 7
  • Man of many talents
    • View Profile
Re: search txt file for a certain number
« Reply #14 on: October 28, 2020, 01:53:26 am »
Solved it, for the curious how I did it.
Code: QB64: [Select]
  1.  
  2. show
  3.  
  4. SUB show
  5.     CLS
  6.     OPEN "durgenDB/consumerprofile.dat" FOR INPUT AS #1
  7.     INPUT " Profile number to find  ", searchnumber
  8.     DO UNTIL EOF(1)
  9.         INPUT #1, IDnumber
  10.         IF IDnumber = searchnumber THEN
  11.             INPUT #1, FirstName$
  12.             INPUT #1, LastName$
  13.             INPUT #1, Address1$
  14.             INPUT #1, Address2$
  15.             INPUT #1, City$
  16.             INPUT #1, State$
  17.             INPUT #1, Zip$
  18.             INPUT #1, Phone$
  19.             INPUT #1, Email$
  20.         END IF
  21.     LOOP
  22.     CLOSE #1
  23.     CLS
  24.     LOCATE 2, 10: PRINT "Costumer Profile": PRINT "-----------------------------------------------------------------"
  25.     LOCATE 4, 10: PRINT "Consumer No.: ": LOCATE 4, 22: PRINT searchnumber
  26.     LOCATE 6, 10: PRINT "Name: ": LOCATE 6, 16: PRINT RTRIM$(FirstName$); " "; RTRIM$(LastName$)
  27.     LOCATE 8, 10: PRINT "Mailing Address: ": LOCATE 8, 27: PRINT Address1$
  28.     LOCATE 10, 10: PRINT "Shipping Address: ": LOCATE 10, 28: PRINT Address2$
  29.     LOCATE 12, 10: PRINT "City: ": LOCATE 12, 16: PRINT City$
  30.     LOCATE 14, 10: PRINT "State: ": LOCATE 14, 17: PRINT State$
  31.     LOCATE 16, 10: PRINT "Zip: ": LOCATE 16, 15: PRINT Zip$
  32.     LOCATE 18, 10: PRINT "Phone: ": LOCATE 18, 17: PRINT Phone$
  33.     LOCATE 20, 10: PRINT "E-Mail: ": LOCATE 20, 18: PRINT Email$
  34.  
  35.     DIM hope AS STRING
  36.     hope = UCASE$(hope)
  37.     LOCATE 23, 10: INPUT "View another Y/N ", hope
  38.     IF UCASE$(hope) = "Y" THEN
  39.         show
  40.     ELSE
  41.         END 'menu
  42.     END IF
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.