Page 1 of 1

create an arra from txt file

PostPosted: Thu Jan 15, 2015 12:27 pm
by Silvio.Falconi
I have a file txt "level1.txt" type :

001700509573024106800501002700295018009400305652800007465080071000159004908007053
029650178705180600100900500257800309600219005900007046573400021800020453010395000
008203500009670408346050702430010059967005001000496203280034067703500904004107020
800005216045862007670009500769204030020001765001670009004096800907400601306107940

I wish insert all into a array having only one field of 81 space

atest:= { Space(81) }

I made this but it make error

cFile:="level1.txt"
ctext:= Memoread(cFile)
nLinea :=MLCOUNT(cTexto)

for n=1 to nLinea
cLinea:=MEMOLINE(cTexto,81,n)
AADD(atest,ALLTRIM(cLinea))
next

the error
It make error because it count me 1998 lines but the sum of lines are 999
then add other fields to array


I cannot post the file because it contains 82748 characters. The maximum number of allowed characters is 60000 for this forum

Re: create an arra from txt file

PostPosted: Thu Jan 15, 2015 1:16 pm
by ukoenig
Silvio,

Code: Select all  Expand view

#include "tselex.ch"

FUNCTION MAIN()
LOCAL oText:= TTxtFile():New( "level1.txt" ), aTest := {}, n

FOR n = 1 to oText:RecCount()
      AADD( aTest,  oText:ReadLine() )
      MsgAlert( aTest[n], "Array-line : " + ALLTRIM(STR(n)) )
      oText:Skip()
NEXT
oText:Close()

RETURN( NIL )
 


Line 2

Image

best regards
Uwe :)

Re: create an arra from txt file

PostPosted: Thu Jan 15, 2015 6:15 pm
by Silvio.Falconi
thanks Uwe,

some files.txt are very very big
how I can make to have a show text type : " Load level2.txt in n seconds"
I try with a timer but it not run good

Re: create an arra from txt file

PostPosted: Fri Jan 16, 2015 3:59 pm
by James Bott
Silvio,

It will be much faster the way you did it--loading the entire file into memory then parsing it, rather than reading each line from the disk.

Your coding mistake is here:

nLinea :=MLCOUNT(cTexto)

Should be:

nLinea :=MLCOUNT(cTexto, 81) // was missing the line length

I would also suggest setting cTexto to nil right after you are done parsing it so the memory will be recovered.

Re: create an arra from txt file

PostPosted: Mon Jan 26, 2015 10:30 pm
by derpipu
Code: Select all  Expand view

FUNCTION Txt2Array( cCAdena, nCaracteres)
  LOCAL aTexto := {}, nCuantos := LEN(cCadena) / nCaracteres, nBrinco := 0
  DEFAULT nCaracteres := 1

  nStart := 1; nxLen := nCaracteres; cxTexto := cCAdena
  cTxt := SUBSTR( cxTexto, nStart, nxLen )

  DO WHILE nBrinco < nCuantos/*! EMPTY(cTxt)*/
    nBrinco++

    AADD(aTexto, cTxt )
    nStart += nxLen
    cTxt := SUBSTR( cxTexto, nStart, nxLen )
  ENDDO

RETURN(aTexto)
 

Re: create an arra from txt file

PostPosted: Tue Jan 27, 2015 9:06 am
by Enrico Maria Giordano
James,

James Bott wrote:I would also suggest setting cTexto to nil right after you are done parsing it so the memory will be recovered.


Better limit the scope of the variable.

EMG

Re: create an arra from txt file

PostPosted: Tue Jan 27, 2015 1:58 pm
by sambomb
FOpen()
Opens a file on the operating system level.
Syntax
FOpen( <cFileName>, [<nMode>]) --> nFileHandle

Arguments
<cFilename>
This is a character string holding the name of the file to open. It must include path and file extension. If the path is omitted from <cFileName>, the file is searched in the current directory.
<nMode>
A numeric value specifying the open mode and access rights for the file. #define constants from the FILEIO.CH file can be used for <nMode> as listed in the table below: File open modes Constant Value Description
FO_READ *) 0 Open file for reading
FO_WRITE 1 Open file for writing
FO_READWRITE 2 Open file for reading and writing
*) default

Constants that define the access or file sharing rights can be added to an FO_* constant. They specify how file access is granted to other applications in a network environment.
File sharing modes Constant Value Description
FO_COMPAT *) 0 Compatibility mode
FO_EXCLUSIVE 16 Exclusive use
FO_DENYWRITE 32 Prevent other applications from writing
FO_DENYREAD 48 Prevent other applications from reading
FO_DENYNONE 64 Allow others to read or write
FO_SHARED 64 Same as FO_DENYNONE
*) default


FRead()
Reads characters from a binary file into a memory variable.
Syntax
FRead( <nFileHandle>, ;
@<cBuffer> , ;
<nBytes> , ;
[<nOffset>] ) --> nBytesRead

Arguments
<nFileHandle>
This is a numeric file handle returned from function FOpen() or FCreate().
@<cBuffer>
A memory variable holding a character string must be passed by reference to FRead(). It must have at least <nBytes> characters.
<nBytes>
This is a numeric value specifying the number of bytes to transfer from the file into the memory variable <cBuffer>, beginning at the current file pointer position.
<nOffset>
This is a numeric value specifying the number of bytes to skip at the beginning of <cBuffer> where the result is copied to. This allows to copy the data from the file into the middle of a string buffer. The default value is zero. Note that the sum of <nBytes>+<nOffset> must be smaller than or equal Len(<cBuffer>).


Code: Select all  Expand view

// The example reads an entire file in blocks of 81 bytes and fills them into an array

   #define BLOCK_SIZE     81

   PROCEDURE Main
      LOCAL cBuffer     := Space( BLOCK_SIZE )
      LOCAL nFileHandle := FOpen( "level1.txt")
      LOCAL aBlocks     := {}
      LOCAL nRead

      IF FError() <> 0
         ? "Error opening file:", FERROR()
         QUIT
      ENDIF

      DO WHILE .T.
         nRead := FRead( nFileHandle, @cBuffer, BLOCK_SIZE )
         IF nRead == BLOCK_SIZE
            AAdd( aBlocks, cBuffer )
         ELSE
            // end of file reached
            AAdd( aBlocks, SubStr(cBuffer,nRead) )
            EXIT
         ENDIF
      ENDDO

      FClose( nFileHandle )
      ? Len( aBlocks ), "Blocks of", BLOCK_SIZE, "bytes read"
   RETURN

 

Re: create an arra from txt file

PostPosted: Thu Jan 29, 2015 12:28 am
by James Bott
Code: Select all  Expand view

//Test program with Str2Array() function.

#include "fivewin.ch"

Function Main()

   local cFile:="level1.txt", cText:="", aArray
   local nLineLength:=81
   local cSample:=""
           
   // Create the sample file
   cSample:= cSample+"001700509573024106800501002700295018009400305652800007465080071000159004908007053"+CRLF
   cSample:= cSample+"029650178705180600100900500257800309600219005900007046573400021800020453010395000"+CRLF
   cSample:= cSample+"008203500009670408346050702430010059967005001000496203280034067703500904004107020"+CRLF
   cSample:= cSample+"800005216045862007670009500769204030020001765001670009004096800907400601306107940"+CRLF
   memowrit( cFile, cSample)

   // Read the file
   cText  := Memoread(cFile)
   
   // convert to an array with line
   aArray:= str2Array( cText, nLinelength )
   
   msgInfo( len(aArray),"Length of array")
   
   msgInfo( aArray[1],"First element of array")
   
return nil

   
Function str2Array( cText, nLineLength )
   local aArray:={}
   local cLine:=""
   local nLines := MLCOUNT( cText, nLineLength )

   for n=1 to nLines
      cLine:=MEMOLINE(cText,nLineLength,n)
      AADD(aArray,cLine)
   next
   
Return aArray