I have been, and want to continue, allowing my users to import long lists from a text file rather than typing them into my program. I have been reading the text file.
dim tis As textInputStream = TextInputStream.Open(f)
if tis <> nil Then
dim theStr As String = tis.ReadAll
iList() = Split(theStr, EndOfLine)
end if
I find that this works only some of the time depending on which app created the text file. I also tried endOfLine.UNIX and the results are the same. When the file was exported as .txt by Pages, it worked both ways. When by Tex-Edit or Text Wrangler, it didn’t split the string correctly either with .UNIX or not.
This is with a Cocoa application.
Is there something I can do other than requiring my users to use Pages to make this work with all word processing apps?
Taking a peek at: http://documentation.xojo.com/index.php/ReplaceLineEndings should clear things up. It handles what to search for. You then replace it with something you know, such as EndOfLine. You can then split on EndOfLine and know that it will do the right thing since all your line endings (of an unknown type) are now of a known type.
Your solution is fine, but if memory is of no concern, a lot of times its faster to read the whole file in one action.
[quote=86238:@Simon Berridge]I have found a universal way that seems to work for me:
[/quote]
What is wrong with ReplaceLineEndings? Dave’s solution does the same thing as yours as far as I can tell, probably quite a bit faster. Yours has some error checking, which is needed but as for the string manipulation. Merging the two just use:
Dim lines() As String
Dim tis As TextInputStream = TextInputStream.Open(f)
If tis <> Nil Then
lines = Split(ReplaceLineEndings(tis.ReadAll, EndOfLIne), EndOfLine)
End If
Simon, I strongly recommend that you look into ReplaceLineEndings. First, it will do all yours does in one line. Second, yours will fail if the text contains a vertical bar so it’s not reliable.
For some of just trusting that the Xojo compiler knows what the line endings are for the replace all EndOfLine is not enough.
I suffer a little from OCD and have had bad experiences with EOL in the past (Delphi, VB). I know that universally EOL is either #13#10 or #13 and my method guarantees that any/either of these will be picked up.
In fact, the last two lines:
theStr = ReplaceAll(theStr, "|", EndOfLine.Unix)
iList() = Split(theStr, EndOfLine.Unix)
can be changed to:
iList() = Split(theStr, "|")
which will save a step.
I am not advocating using my method, just stating that this is what I use for reading and parsing text files. My programs use a lot of text input and some of the files run into megabytes of data (for a text file that is huge). I see virtually no change in the speed!
I have just seen Kem’s reply. I don’t advocate “|”, it was used as an example. It very much depends upon whether you know the input style or not. I have used “±” and “§” as well! I have to admit to using ReplaceLineEndings too, but I just have a doubt in my mind every time I do!
Just run a few tests. I’m sure you’ll find that ReplaceLineEndings is much more reliable and faster. No more reason to not trust it than the Split, Mid, Left, Right, or ReplaceAll methods (i.e. any other method Xojo provides for your use).
I question that it doesn’t look like it will actually do anything!
Also, Split, Mid, Left etc. all work on straight text whereas EOL can be one of two different things and my little mind has some trouble in understanding how iy knows the difference!
Just my OCD!
ReplaceLineEndings works fine, I know, I have used it as well. However, I do not use it for my commercial apps as I just can’t control what files my users are loading!
I question that it doesn’t look like it will actually do anything![/quote]
Maybe the docs would help. What ReplaceLineEndings does is replace all various line ending styles with 1 line ending style. So, it only needs 2 parameters, 1 being the string to do the work on and 2 being the line ending that you want to replace all the various line endings with. So…
str = ReplaceLineEndings("Hi\
How are you\\rWhat are you doing\\r\
Today\
\\r", EndOfLine)
Will result in str having only 1 line ending style, that of EndOfLine. It will now look like:
"Hi\
How are you\
What are you doing\
Today\
"
You than then split based on that one line ending, EndOfLine
[quote=86238:@Simon Berridge]I have found a universal way that seems to work for me:
dim tis As textInputStream = TextInputStream.Open(f)
if tis <> nil Then
dim theStr As String = tis.ReadAll
theStr = ReplaceAll(theStr, Chr(13), "|")
theStr = ReplaceAll(theStr, Chr(10), "|")
theStr = ReplaceAll(theStr, "||", "|")
theStr = ReplaceAll(theStr, "|", EndOfLine.Unix)
iList() = Split(theStr, EndOfLine.Unix)
end if
[/quote]
Yeah dont do this this way
You will never be able to put | in your text
Just do
if tis <> nil Then
dim theStr As String = tis.ReadAll
theStr = replaceLineEndings( theStr , endofline)
iList() = Split(theStr, EndOfLine)
end if
Its the right way to do it since ReplaceLineEndings will run FIRST and return a string that has one consistent form of line ending which you then split on