Author Topic: Loading contents of a file into an array  (Read 2967 times)

0 Members and 1 Guest are viewing this topic.

Offline random1

  • Newbie
  • Posts: 86
    • View Profile
Loading contents of a file into an array
« on: August 06, 2019, 07:16:58 pm »
Hi all

Need help loading the entire contents of a .txt into an array.  Below is what I am using now.
The file has 1000 entries / lines and I would like to load the entire file without having to use
line input. 

dim myarray(1 to 1000) as string

Erase myarray

L1=1
Open "file.txt" for input as #1
do while not eof(1)
line input #1, dat1$
dat1$=ltrim$(rtrim$(dat1$))
myarray(L1) = dat1$
L1=L1+1
loop
close

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Loading contents of a file into an array
« Reply #1 on: August 06, 2019, 08:26:55 pm »
Hi random1

Can I call you rnd for short?

Well I see this is a trick question, binary access does not like string arrays.

So here is a trick answer:
Code: QB64: [Select]
  1.  
  2. DIM myarray(1 TO 20) AS STRING * 60 '<<<<<<<<<<< compilation error....  blah phooey!
  3. FOR i = 1 TO 20
  4.     myarray$ = myarray$ + LEFT$("This is line " + STR$(i) + SPACE$(60), 60)
  5.     'myarray(i) = LEFT$("This is line " + STR$(i) + SPACE$(60), 60)  '<<<<<<<<<<< compilation error....
  6.  
  7. OPEN "file.txt" FOR BINARY AS #1
  8. PUT #1, , myarray$
  9. 'PUT #1, , myarray() '<<<<<<<<<<< compilation error....
  10.  
  11. 'ERASE myarray
  12.  
  13. 'alternate open
  14. OPEN "file.txt" FOR BINARY AS #1
  15. l = LOF(1)
  16. myarray$ = SPACE$(l)
  17. GET #1, , myarray$
  18. 'GET #1, , myarray() '<<<<<<<<<<< compilation error....
  19. FOR i = 1 TO 20
  20.     PRINT MID$(myarray$, (i - 1) * 60 + 1, 60)
  21.     'PRINT myarray(i) '<<<<<<<<<<< compilation error....
  22.  

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Loading contents of a file into an array
« Reply #2 on: August 06, 2019, 08:56:15 pm »
Hi random1

Can I call you rnd for short?

Well I see this is a trick question, binary access does not like string arrays.

Binary access works lovely fine with string arrays; you just need to read and parse for them:

Code: QB64: [Select]
  1. DIM array(10000) AS STRING
  2.  
  3. OPEN "temp.txt" FOR OUTPUT AS #1
  4. FOR i = 1 TO 10000
  5.     PRINT #1, "Junk Line of Input #"; i
  6.  
  7. OPEN "temp.txt" FOR BINARY AS #1 'Load the data
  8. l = LOF(1) 'all of it at once
  9. junk$ = SPACE$(l)
  10. GET #1, 1, junk$ 'The file is now in junk$
  11.  
  12.  
  13. ParseData array(), junk$ 'And we parse junk$ into our array
  14. FOR i = 1 TO 10
  15.     PRINT i, array(i) 'first 10 results
  16. PRINT ".... Skip a few..."
  17. FOR i = UBOUND(array) - 10 TO UBOUND(array)
  18.     PRINT i, array(i) 'last 10 results
  19.  
  20.  
  21. SUB ParseData (array() AS STRING, text$)
  22.     temp$ = text$
  23.     IF INSTR(text$, CHR$(13)) THEN CRLF = 2 ELSE CRLF = 1
  24.     DO
  25.         IF l >= LEN(temp$) THEN EXIT DO
  26.         l = INSTR(temp$, CHR$(10))
  27.         count = count + 1
  28.         array(count) = LEFT$(temp$, l - CRLF)
  29.         temp$ = MID$(temp$, l + 1)
  30.     LOOP
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: Loading contents of a file into an array
« Reply #3 on: August 06, 2019, 08:59:06 pm »
Rats SAM, you beat me :D
Code: QB64: [Select]
  1.  
  2. REDIM myarray(1 TO 20) AS STRING 'make a test array
  3. FOR i = 1 TO 20
  4.     myarray(i) = "This is line " + STR$(i)
  5.     B$ = B$ + myarray(i) + CHR$(13) + CHR$(10)
  6.  
  7. OPEN "file.txt" FOR BINARY AS #1
  8. PUT #1, , B$
  9.  
  10. ' we have a sequential file of strings to load
  11. REDIM myarray(0) AS STRING
  12.  
  13. 'alternate open
  14. OPEN "file.txt" FOR BINARY AS #1
  15. l = LOF(1)
  16. B$ = SPACE$(l)
  17. GET #1, , B$
  18.  
  19. Split1000 B$, CHR$(13) + CHR$(10), myarray()
  20. FOR i = 0 TO UBOUND(myarray)
  21.     PRINT myarray(i)
  22.  
  23. 'notes: REDIM the array(0) to be loaded before calling Split '<<<<<<<<<<<<<<<<<<<<<<< IMPORTANT!!!!
  24. SUB Split1000 (mystr AS STRING, delim AS STRING, arr() AS STRING)
  25.     ' bplus modifications of Galleon fix of Bulrush Split reply #13
  26.     ' http://xmaxw.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=1612.0
  27.     ' this sub further developed and tested here: \test\Strings\Split test.bas
  28.     DIM copy AS STRING, p AS LONG, curpos AS LONG, arrpos AS LONG, dpos AS LONG, LD AS INTEGER
  29.  
  30.     copy = mystr 'make copy since we are messing with mystr when the delimiter is a space
  31.  
  32.     'special case if delim is space, probably want to remove all excess space
  33.     IF delim = " " THEN
  34.         copy = RTRIM$(LTRIM$(copy))
  35.         p = INSTR(copy, "  ")
  36.         WHILE p > 0
  37.             copy = MID$(copy, 1, p - 1) + MID$(copy, p + 1)
  38.             p = INSTR(copy, "  ")
  39.         WEND
  40.     END IF
  41.     curpos = 1
  42.     arrpos = 0
  43.     LD = LEN(delim) 'mod
  44.     dpos = INSTR(curpos, copy, delim)
  45.     DO UNTIL dpos = 0
  46.         arr(arrpos) = MID$(copy, curpos, dpos - curpos)
  47.         arrpos = arrpos + 1
  48.         IF arrpos > UBOUND(arr) THEN REDIM _PRESERVE arr(UBOUND(arr) + 1000) AS STRING
  49.         curpos = dpos + LD
  50.         dpos = INSTR(curpos, copy, delim)
  51.     LOOP
  52.     arr(arrpos) = MID$(copy, curpos)
  53.     REDIM _PRESERVE arr(arrpos) AS STRING 'need this line? YES to get the ubound correct
  54.  
  55.  
  56.  

Quote
Binary access works lovely fine with string arrays; you just need to read and parse for them:
I still say, Binary access does not like string arrays, SAM is the one one who works "lovely fine" with string arrays.

You can't do this with strings:
Code: QB64: [Select]
  1. DIM myarray(1 TO 20) AS INTEGER
  2. FOR i = 1 TO 20
  3.     myarray(i) = i ^ 2
  4. OPEN "mySquares.dat" FOR BINARY AS #1
  5. PUT #1, , myarray()
  6. ERASE myarray
  7. OPEN "mySquares.dat" FOR BINARY AS #1
  8. GET #1, , myarray()
  9. FOR i = 1 TO 20
  10.     PRINT myarray(i)
  11.  

You can't even do it with fixed length strings.

And now Pete will say, "That's because they have been fixed."
« Last Edit: August 06, 2019, 09:16:53 pm by bplus »

Offline random1

  • Newbie
  • Posts: 86
    • View Profile
Re: Loading contents of a file into an array
« Reply #4 on: August 07, 2019, 03:36:30 pm »
Hi all

Thanks for all the replies, got me thinking.  Since all the strings in the files are fixed
length, why not just load the data into a string using open & binary and then process
the string much the same way I would an array.   The goal was to speed up the time
it takes to load and process over 200 files.   
The stuff posted here will not go to waste, it's going into my tool-box as i am sure I will
make use of it down the road.

Thanks again

R1 
     

   
 
 

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Loading contents of a file into an array
« Reply #5 on: August 07, 2019, 04:37:01 pm »

I still say, Binary access does not like string arrays, SAM is the one one who works "lovely fine" with string arrays.

You can't do this with strings:
Code: QB64: [Select]
  1. DIM myarray(1 TO 20) AS INTEGER
  2. FOR i = 1 TO 20
  3.     myarray(i) = i ^ 2
  4. OPEN "mySquares.dat" FOR BINARY AS #1
  5. PUT #1, , myarray()
  6. ERASE myarray
  7. OPEN "mySquares.dat" FOR BINARY AS #1
  8. GET #1, , myarray()
  9. FOR i = 1 TO 20
  10.     PRINT myarray(i)
  11.  

You can't even do it with fixed length strings.

And now Pete will say, "That's because they have been fixed."

For random length strings, you can do it like so:
Code: QB64: [Select]
  1. DIM myarray(1 TO 20) AS STRING
  2. DIM myarray2(1 TO 20) AS STRING
  3.  
  4. OPEN "mySquares.dat" FOR BINARY AS #1
  5. FOR i = LBOUND(myarray) TO UBOUND(myarray)
  6.     junk$ = "This is just some random length junk string"
  7.     myarray(i) = MID$(junk$, INT(RND * 10), INT(RND * LEN(junk$)))
  8.     l& = LEN(myarray(i)) 'get the string size
  9.     PUT #1, , l& 'put the size value
  10.     PUT #1, , myarray(i) 'put the string
  11.  
  12. OPEN "mySquares.dat" FOR BINARY AS #1
  13. FOR i = LBOUND(myarray2) TO UBOUND(myarray2)
  14.     GET #1, , l& 'get the size
  15.     myarray2(i) = SPACE$(l&) 'set our string to recieve that size
  16.     GET #1, , myarray2(i) 'get the string
  17. FOR i = 1 TO 20
  18.     PRINT myarray(i); TAB(40); myarray2(i)
  19.  



And when it comes to fixed length string arrays, you can do them even easier: 
Code: QB64: [Select]
  1. DIM myarray(1 TO 20) AS STRING * 40
  2.  
  3. OPEN "mySquares.dat" FOR BINARY AS #1
  4. FOR i = LBOUND(myarray) TO UBOUND(myarray)
  5.     junk$ = "This is just some random length junk string"
  6.     myarray(i) = MID$(junk$, INT(RND * 10), INT(RND * LEN(junk$)))
  7. temp$ = myarray()
  8. PUT #1, , temp$
  9.  
  10. OPEN "mySquares.dat" FOR BINARY AS #1
  11. temp$ = SPACE$(LEN(myarray())) 'clear the string so we know we're getting it anew.
  12. GET #1, , temp$ 'get the whole array
  13. myarray() = temp$
  14. FOR i = 1 TO 20
  15.     PRINT i, myarray(i)

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: Loading contents of a file into an array
« Reply #6 on: August 07, 2019, 06:43:31 pm »
Hi Steve,

The first demo, not so impressive, you are doing things line by line maybe even slower than a sequential file and load, certainly more complex.

2nd code demo opens my eyes, you can set a string to an array and vice versa! ? ! That is cool! There you are doing things in file chunks.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Loading contents of a file into an array
« Reply #7 on: August 07, 2019, 07:00:17 pm »
Hi Steve,

The first demo, not so impressive, you are doing things line by line maybe even slower than a sequential file and load, certainly more complex.

Aye, but since you’re working with variable length strings, you either need to know the size or have a separator character to keep them apart.  If your string might hold control characters (Array(1) = “Hello” + CHR$(13) + “World”), you can’t count on LINE INPUT working properly for you (it’d read the above as 2 lines and not one).  When terminators aren’t possible, size has to be stored separate just so you know what’s what in the file.

“Welikecheese” — one word?  Two 6-letter words?  Three words?  With variable length data, we honestly have no way of knowing, without either recording the size or using a terminator code.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!