iOS Question Space delimted text file

Graeme Mitchell

Member
Licensed User
I am using the httpjob to download the txt file from the server, I can see the string of the download. The text file is space delimited, i know the breakdown of the field, in this case it is 40,15,3,47.

B4X:
Dim j As HttpJob
   j.Initialize("", Me)
   j.Download(filename)
   Wait For (j) JobDone(j As HttpJob)
   If j.Success Then
       Log(j.GetString)
   End If
   j.Release

I know the code works for the download, I know that I need to put something in the j.success if statement but how would I parse the string, there are 4 columns and 5 lines of text

Thanks
 

Brandsum

Well-Known Member
Licensed User
First explode the string using CRLF (new line char) as delimiter. You will get each line as a string. Then run a loop and explode each string using space as delimeter.
 
Upvote 0

emexes

Expert
Licensed User
Space-delimited sometimes means fixed-format, eg:
B4X:
A Alpha   Sunday    1  1  
B Brava   Monday    2  2
C Charlie Tuesday   3  4
D Delta   Wednesday 4  8
E Echo    Thursday  5 16
F Foxtrot Friday    6 32
G Golf    Saturday  7 64
and so you might need to watch out for:
- multiple spaces = single delimiter
- how empty/blank/null fields are handled
- leading spaces (if generates a blank extra field, then subsequent field numbering could be off-by-one)
- trailing spaces (if generates a blank extra field, then could overrun your Dim Field(NumFields) As String buffer array)
 
Upvote 0

Graeme Mitchell

Member
Licensed User
You are correct, it is a fixed-width file, so as per the suggestion above I am going to use the CRLF as a delimiter and read that into a string. I think I will try to substring the above string with the column widths I have in an array. Does that sound about right?
 
Upvote 0

emexes

Expert
Licensed User
Substring sounds 100% right for your case of fixed-length input.

Just be sure that it is spaces between the columns, and not tabs (ASCII control code 9) - they sometimes look very similar.
 
Upvote 0

emexes

Expert
Licensed User
Often some columns will contain predictable characters, eg: blank space between fields, decimal point, digit, letter, even anything-except-space.

You can use these columns to do a preliminary filter sanity check on each line, before you split it into fields.

Also, .Trim will probably become your favorite string function ;-)
 
Upvote 0

emexes

Expert
Licensed User
Just noticed that you have the column widths in an array. You could use those to do the preliminary filter, by checking that:

- each field (except the first one) is preceded by a space
- each field begins with a non-space (unless empty fields are possible, eg, a person's middle name)
B4X:
'000000000011111111112222222222333333333344444444445555555555  position
'012345678901234567890123456789012345678901234567890123456789
'
'Bill  Bloggs      123 Fourth Street    Fifthville
'Dan   Dubois      345 Fifth Road       Sixthville
'Erel  Eminent     567 Sixth Avenue     Seventhville
'
'00000 11111111111 22222222222222222222 333333333333333333333  field number (NOTE NumFields = 4, not 3 ;-)
'5     11          20                   21                     field width
'========================================                      minimum line length = 4 + (5 + 11 + 20) = 40

Dim MinLineLength As Int = NumFields    'preload with column-separating spaces and first character of last field
For FieldNumber = 0 to NumFields - 2
    MinLineLength = MinLineLength + FieldLength(FieldNumber)
Next

For Each LineString in the file
    Dim OkFlag As Boolean

    OkFlag = (LineString.Length >= MinLineLength)

    If OkFlag Then
        Dim FieldPosition As Int = 0
        For FieldNumber = 0 to NumFields - 1
            If FieldNumber <> 0 Then
                If LineString.CharAt(FieldPosition - 1) <> " " Then
                    OkFlag = False
                    Exit    'Exit For, since no need to check any further
                End If
            End If

            If LineString.CharAt(FieldPosition) = " " Then
                OkFlag = False
                Exit    'Exit For, since no need to check any further
            End If

            FieldPosition = FieldPosition + FieldLength(FieldNumber) + 1
        Next
    End If

    If OkFlag Then
        CallYourOwnSplitLineRoutine()    'line looking good so far
    Else
        Log("Line failed filter test")
        Log("[" & LineString & "]"
    End If
Loop
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Sorry, might have overdone it there. On the bright side, I'm watching tv at the moment, so it helped fill the ad breaks. :)
 
Upvote 0
Top