Tom Verhoeff wrote:
On Wed, Sep 29, 2004 at 06:22:50PM +0200, Frank Heckenbach wrote:
So my proposal is to add (now or later):
function String2Num(???) (const s: String; var n: <numeric type>): Boolean;
Comments?
I would find it more appropriate to have a routine that works more like read, but then on a string instead of a text file. It should accommodate various types, and it should somehow indicate how much of the string has actually been converted, so that you can easily pick up where the conversion stopped.
That's `Val' (BP routine, implemented in GPC for a long time).
- Somehow return the character index of the first character that was NOT converted.
That's what `Val' does (in the 3rd parameter).
In that case, it might be convenient to provide the conversion routine with a starting index for the conversion, rather than just start at the beginning.
No need to since it can easiy be accomplished using `SubStr', `Copy' or a string slice (`s[i .. j]').
It would be nice if you could easily "string" together a sequence of conversions to extract a sequence of values from a string. And it would also be nice if you could write your own customized conversion routines (e.g. for more complex types), using same approach.
Let's assume var S: String; n, i: Integer; x: Real; r: MyRec;
In case of 1, you would have
function String2Num ( const S: String; var i: Integer; var n: <numeric type>): Boolean;
and you could "string" together
i := StartValue ; String2Num ( S, i, n ) ; String2Num ( S, i, x ) ; String2MyRec ( S, i, r )
In case of 2, you would have
function String2Num ( var S: String; var n: <numeric type>): Boolean;
String2Num ( S, n ) ; String2Num ( S, x ) ; String2MyRec ( S, r )
Of course, this ignores the issue of error (exception) handling. But I hope that the idea is clear.
Well, error handling is what this discussion is all about. Otherwise you can just use ReadStr:
ReadStr (S, n, x, r);
An alternative is to take the approach of sscanf from C, where you extract a sequence of items from a string according to some format,
Even if Scott hasn't yet posted his usual rant by the time my mail is sent ;-), I'd also express my objections against using runtime format strings. I can't see a reason they'd be useful (since the parameters, and therefore the types to be read, must be known at compil time, anyway).
So in a way, `ReadStr' is `sscanf' without the obnoxious format string. (The compiler knows the types to read already by itself.)
By the way, I don't like the name "String2Num". How about "StrToNum"? Delphi has a whole set of StrTo... functions. These raise the exception EConvertError in case of an error.
So I suppose they don't return a Boolean then? Then in fact it may be preferable to use a different name here to avoid confusion. Apart from that, I wouldn't mind StrToNum personally.
Skipping of leading white space seems natural to me when converting numbers (that is what "read" does as well). But, as you say, it could be handled separately (basically it is a TrimLeft). On the other hand, it is also awkward to dilute your code with many such Trim operations. I would surmise that users will (also) want a single routine that converts a number, while skipping leading whitespace.
In fact `Val' does so (in BP and GPC), as well as `ReadStr' (EP and GPC). Sorry if I stated this wrongly. So the new function would also do it.
Frank