I have a string of data 4 columns wide, tab delimited with end of line character at the end of each line. I thought I could use the Spilt function to split this into an array but it only does 1D arrays. What are my options? I assume loop through and use mid to split the lines out and then split by tab?
Get an array of lines with input.Split( EndOfLine )
, then loop through those and aLine.Split( tabChar )
. You can then assign each value to a 2D array if you’d like.
A specific end of line character should be used for the call to Split
and not EndOfLine
, since the latter is platform-specific.
Right, I should have written input.Split( eolChar )
since this was illustrative code.
Thanks Gents
By the way, in the M_String module on my web site, there is a very fast EndOfLineOf method that will tell you what the EOL character of an existing string is. It looks like this:
Protected Function EndOfLineOf(src As String, defaultEOL As String = "") As String
// Finds the end of line of a string.
// If there is no end of line character found, returns the default, even if the default is nothing.
// Break it down to bytes rather than doing a repeated search. The first byte that matches will
// end the search so it will be faster than using InStr or even InStrB and trying the wrong EOL
// character first.
// Note that if the text contains a stray linefeed or return (a gremlin), the result could be incorrect.
#pragma BoundsChecking False
#pragma BackgroundTasks False
// Convert the encoding to make sure the byte comparison for the EOL characters works properly.
// In UTF-8, bytes that represent ascii characters are only used for that purpose.
// Only convert if the encoding is not UTF-8 and it has multibyte characters.
dim origEncoding as TextEncoding = src.Encoding
if origEncoding <> Encodings.UTF8 and src.HasMultiByteChars_MTC then
src = src.ConvertEncoding( Encodings.UTF8 )
end if
// Optimization -- See if the last byte is an EOL
// If so, reduce it to the last 2 bytes
dim lastByte as integer = src.RightB( 1 ).AscB
if lastByte = 10 or lastByte = 13 then src = src.RightB( 2 )
dim mb as MemoryBlock = src
dim p as Ptr = mb
dim lastIndex as integer = mb.Size - 1
dim eol as string
// Work backwards in case the string ends with an EOL character, saving a bunch of time
for byteIndex as integer = lastIndex downTo 0
dim thisByte as integer = p.Byte( byteIndex )
select case thisByte
case 10 // linefeed
// See if it's preceded by a return
if byteIndex <> 0 and p.Byte( byteIndex - 1 ) = 13 then
eol = EndOfLine.Windows
else
eol = EndOfLine.Unix
end if
exit
case 13 // carriage return
eol = EndOfLine.Macintosh
exit
end select
next
if eol = "" then // Nothing found, so set it to defaultEOL
eol = defaultEOL // No encoding change
else
eol = eol.ConvertEncoding( origEncoding ) // Convert it back to the original encoding
end if
return eol
End Function
Thanks Kem, I’ll take a look at that…