StringToStream error???
- To: mathgroup at yoda.physics.unc.edu
- Subject: StringToStream error???
- From: Simon Chandler <simonc at hpcpbla.bri.hp.com>
- Date: Mon, 24 Aug 92 14:02:01 +0100
Dear Mathematica users,
I have come across a VERY peculiar problem when using the StringToStream
function. I'm sorry this isn't very consise but its necessary to describe the
problem.
I have a function that reads text data of format
n1, n2, n3, n4 lf cr
m1, m2, m3, m4, lf cr where lf is a linefeed and cr a return.
into a list of lists of strings, like so
{{n1,n2,n3,n4},{m1,m2,m3,m4}}.
i.e. Head[n1] is a String. This function is... *)
readData[textFileName_]:=
Module[
{newInputStream=OpenRead[textFileName],theData},
theData=
ReadList[
newInputStream,
Word,
RecordLists->True,
NullWords->False,
WordSeparators->{" ",",","\.0d","\.0a"}
];
Close[newInputStream];
theData
];
(*
The elements in the text file are scientific notation i.e. 1E-5 or 100.00 and
may contain leading spaces. For reasons I won't go in to I must initially
read the data as Strings and then later convert them to Reals by using the
StringToStream function. To this end I define a function that will Parse a
string parameter... *)
SetAttributes[stringToNumber,Listable];
stringToNumber[theString_String]:=
Module[{theStream=StringToStream[theString],theNumber},
theNumber=Read[theStream,Number];
Close[theStream];
theNumber
];
stringToNumber[anythingElse_]:=anythingElse;
(*
This works well if the text file ends with anything other than a linefeed,
carrage return pair. If the file does end with this pair of characters it
fails in a very strange way !!!
To demonstrate... *)
linefeed="\.0a"; (* define delimiters *)
return="\.0d";
comma="\.2c";
(* write a file ending with a linefeed, i.e., omit the last carrage return *)
WriteString[
"nolfcr.test",
11,comma,22,linefeed,return,
33,comma,44,linefeed
];
Close["nolfcr.test"];
!! nolfcr.test
(* you should get...
11,22
33,44
*)
(* now write a file ending with a linefeed and carrage return *)
WriteString[
"lfcr.test",
11,comma,22,linefeed,return,
33,comma,44,linefeed,return
];
Close["lfcr.test"];
!! lfcr.test
(* again you should get
11,22
33,44
*)
(* Now read in the file that omitted the last carrage return*)
datanolfcr=readData["nolfcr.test"];
(* and convert it *)
stringToNumber[datanolfcr]
(* you should get the correct result ...
{{11, 22}, {33, 44}}
*)
(* Now read in the file that ended with linefeed, carrage return*)
datalfcr=readData["lfcr.test"];
stringToNumber[datalfcr]
(* this time you will get...
{{1, 22}, {33, 44}}
which for some strange reason misses the first character *)
(* but try the conversion again and everything sorts itself out*)
stringToNumber[datalfcr]
(*gives ...
{{11, 22}, {33, 44}}
*)
(* I have checked using Trace but this does not reveal what's happening.
The lists of strings 'datanolfcr' and 'datalfcr' seem identical so the error
is happening in the stringToNumber routine. Can anyone see where this
is going wrong or a better way of doing this job ?
Thanks for reading this far,
I hope you can help me.
Simon Chandler
Hewlett-Packard Ltd
CPB
Bristol
tel: +44 272 228109
fax: +44 272 236091
email: simonc at hpcpbla.bri.hp.com *)