Jump to page: 1 2
Thread overview
stream.scanf change proposal
Jul 01, 2005
Ben Hinkle
Jul 01, 2005
Regan Heath
Jul 01, 2005
Andrew Fedoniouk
Jul 01, 2005
Sean Kelly
Jul 01, 2005
Andrew Fedoniouk
Jul 01, 2005
Sean Kelly
Jul 01, 2005
Andrew Fedoniouk
Jul 01, 2005
Sean Kelly
Jul 01, 2005
Andrew Fedoniouk
Jul 01, 2005
Sean Kelly
Jul 02, 2005
Ben Hinkle
Jul 02, 2005
Sean Kelly
Jul 02, 2005
Ben Hinkle
Jul 02, 2005
Sean Kelly
Jul 01, 2005
Ben Hinkle
Jul 01, 2005
Sean Kelly
Jul 01, 2005
Nick
Jul 01, 2005
Ben Hinkle
Jul 02, 2005
Nick
July 01, 2005
Vathix's post on the bugs newsgroup about std.stream issue raised the topic
of reading and converting text input to binary data like ints and floats and
such. Currently std.stream has a scanf and vscanf that were written ages ago
(probably before _argptr and _arguments existed) and I'd like to update them
to the more modern D style much like Sean's unformat and/or readf. So
basically the change would be to change the signature of scanf and vscanf
from
  int scanf(char[] fmt, ...);
  int vscanf(char[] fmt, va_list args);
to
  int scanf(...);
  int vscanf(TypeInfo[] arguments, va_list args);
and modify the format specifiers to match std.format instead of std.c.stdio.
In other words if the format string is omitted then the TypeInfo for the
argument is used to deduce a default format. For instance
  int x,y,z;
  din.scanf(&x, &y," and then ", &z);
would take an input line like "123 567 and then 987" and fill x with 123, y
with 567 and z with 987. Explicit format specifiers would be allowed, too.
eg din.scanf("%d %d and then %d",&x,&y,&z);
Such a change is not backwards compatible with previous dmd versions but I
think it is worth breaking from the C style in this case. The last example
indicates many simple scanf calls will continue to work just fine. From what
I can tell this is very similar to what Sean has implemented.
thoughts?


July 01, 2005
I like it. But, I've never used scanf in C, and I haven't yet used it in D either. So I might not have the right perspective to answer.

Regan

On Thu, 30 Jun 2005 21:53:01 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote:
> Vathix's post on the bugs newsgroup about std.stream issue raised the topic
> of reading and converting text input to binary data like ints and floats and
> such. Currently std.stream has a scanf and vscanf that were written ages ago
> (probably before _argptr and _arguments existed) and I'd like to update them
> to the more modern D style much like Sean's unformat and/or readf. So
> basically the change would be to change the signature of scanf and vscanf
> from
>   int scanf(char[] fmt, ...);
>   int vscanf(char[] fmt, va_list args);
> to
>   int scanf(...);
>   int vscanf(TypeInfo[] arguments, va_list args);
> and modify the format specifiers to match std.format instead of std.c.stdio.
> In other words if the format string is omitted then the TypeInfo for the
> argument is used to deduce a default format. For instance
>   int x,y,z;
>   din.scanf(&x, &y," and then ", &z);
> would take an input line like "123 567 and then 987" and fill x with 123, y
> with 567 and z with 987. Explicit format specifiers would be allowed, too.
> eg din.scanf("%d %d and then %d",&x,&y,&z);
> Such a change is not backwards compatible with previous dmd versions but I
> think it is worth breaking from the C style in this case. The last example
> indicates many simple scanf calls will continue to work just fine. From what
> I can tell this is very similar to what Sean has implemented.
> thoughts?
>
>

July 01, 2005
Ben, small question:

Lets say we have:
char* a;
char* b;

How then you will distinguish cases:
din.scanf("%s",a);
din.scanf(a, b);

If we would have const and const literals then it will be possible. But without them it is sort of ambiguity as far as I understand.

Correct me if....

Andrew.


> In other words if the format string is omitted then the TypeInfo for the argument is used to deduce a default format. For instance



"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:da27lu$2i9v$1@digitaldaemon.com...
> Vathix's post on the bugs newsgroup about std.stream issue raised the
> topic of reading and converting text input to binary data like ints and
> floats and such. Currently std.stream has a scanf and vscanf that were
> written ages ago (probably before _argptr and _arguments existed) and I'd
> like to update them to the more modern D style much like Sean's unformat
> and/or readf. So basically the change would be to change the signature of
> scanf and vscanf from
>  int scanf(char[] fmt, ...);
>  int vscanf(char[] fmt, va_list args);
> to
>  int scanf(...);
>  int vscanf(TypeInfo[] arguments, va_list args);
> and modify the format specifiers to match std.format instead of
> std.c.stdio. In other words if the format string is omitted then the
> TypeInfo for the argument is used to deduce a default format. For instance
>  int x,y,z;
>  din.scanf(&x, &y," and then ", &z);
> would take an input line like "123 567 and then 987" and fill x with 123,
> y with 567 and z with 987. Explicit format specifiers would be allowed,
> too. eg din.scanf("%d %d and then %d",&x,&y,&z);
> Such a change is not backwards compatible with previous dmd versions but I
> think it is worth breaking from the C style in this case. The last example
> indicates many simple scanf calls will continue to work just fine. From
> what I can tell this is very similar to what Sean has implemented.
> thoughts?
> 


July 01, 2005
In article <da27lu$2i9v$1@digitaldaemon.com>, Ben Hinkle says...
>
>Vathix's post on the bugs newsgroup about std.stream issue raised the topic of reading and converting text input to binary data like ints and floats and such. Currently std.stream has a scanf and vscanf that were written ages ago (probably before _argptr and _arguments existed) and I'd like to update them to the more modern D style much like Sean's unformat and/or readf.

I think it's a good idea.  The existing implementation of stream.scanf is a bit spotty anyway.  You're welcome to use my code though the current implementation relies on a modified version of std.utf as well.  I just merged recent updates to std.utf into the stdio.zip file I have on my website in case you want to use it.


Sean


July 01, 2005
In article <da2bs0$2ptk$1@digitaldaemon.com>, Andrew Fedoniouk says...
>
>Ben, small question:
>
>Lets say we have:
>char* a;
>char* b;
>
>How then you will distinguish cases:
>din.scanf("%s",a);
>din.scanf(a, b);
>
>If we would have const and const literals then it will be possible. But without them it is sort of ambiguity as far as I understand.

The way I did this was kind of weird.  I assumed that D arrays (char[], etc)
were format strings and C pointers and pointers to arrays (ie. char*, char[]*,
etc) were input parameters.


Sean


July 01, 2005
"Sean Kelly" <sean@f4.ca> wrote in message news:da2ejm$2s5v$1@digitaldaemon.com...
> In article <da2bs0$2ptk$1@digitaldaemon.com>, Andrew Fedoniouk says...
>>
>>Ben, small question:
>>
>>Lets say we have:
>>char* a;
>>char* b;
>>
>>How then you will distinguish cases:
>>din.scanf("%s",a);
>>din.scanf(a, b);
>>
>>If we would have const and const literals then it will be possible. But without them it is sort of ambiguity as far as I understand.
>
> The way I did this was kind of weird.  I assumed that D arrays (char[],
> etc)
> were format strings and C pointers and pointers to arrays (ie. char*,
> char[]*,
> etc) were input parameters.

I see. A bit optimstic, IMO.

Why just not use another and distinct function for that?

Like parse()?

In any case classic scanf (with explicit format) combined with D's TypeInfo[] vector is unbeatable, IMO.

Andrew.


>
>
> Sean
>
> 


July 01, 2005
In article <da2n8i$2gc$1@digitaldaemon.com>, Andrew Fedoniouk says...
>>
>> The way I did this was kind of weird.  I assumed that D arrays (char[],
>> etc)
>> were format strings and C pointers and pointers to arrays (ie. char*,
>> char[]*,
>> etc) were input parameters.
>
>I see. A bit optimstic, IMO.

Since D doesn't allow 'inout' varargs, I thought it quite unlikely someone would pass a standard array in to be written into.  And I thought it was reasonable to assert that all pointer types were input parameters (particularly since literal strings are typed as arrays, not char pointers).

>Why just not use another and distinct function for that?
>
>Like parse()?

The first cut implemented the C99 scanf spec exactly, so this wasn't an option.

>In any case classic scanf (with explicit format) combined with D's TypeInfo[] vector is unbeatable, IMO.

I personally like the way I have it now--format strings are only necessary if you're expecting something in an odd format or if you want to match (and ignore) portions of the input stream.  But it would be easy enough to always interpret the first argument as a format string.


Sean


July 01, 2005
"Sean Kelly" <sean@f4.ca> wrote in message news:da2o30$39n$1@digitaldaemon.com...
> In article <da2n8i$2gc$1@digitaldaemon.com>, Andrew Fedoniouk says...
>>>
>>> The way I did this was kind of weird.  I assumed that D arrays (char[],
>>> etc)
>>> were format strings and C pointers and pointers to arrays (ie. char*,
>>> char[]*,
>>> etc) were input parameters.
>>
>>I see. A bit optimstic, IMO.
>
> Since D doesn't allow 'inout' varargs, I thought it quite unlikely someone
> would
> pass a standard array in to be written into.  And I thought it was
> reasonable to
> assert that all pointer types were input parameters (particularly since
> literal
> strings are typed as arrays, not char pointers).
>
>>Why just not use another and distinct function for that?
>>
>>Like parse()?
>
> The first cut implemented the C99 scanf spec exactly, so this wasn't an option.

Seems like I didn't get something....

My thought was:

scanf(char[], ...);
and
parse(...);

First one used with mandatory format parameter.
Second - "formatless" parsing.
-------------------

In fact these functions will definitely benefit from const

int  a;
char b[20];
int  c[3];

parse(&a, b, " - ",  c);

will read 20 chars into b;
and 3 ints into c;

Of course this will work only if string literal will be const char[].

>
>>In any case classic scanf (with explicit format) combined with D's TypeInfo[] vector is unbeatable, IMO.
>
> I personally like the way I have it now--format strings are only necessary
> if
> you're expecting something in an odd format or if you want to match (and
> ignore)
> portions of the input stream.  But it would be easy enough to always
> interpret
> the first argument as a format string.
>
>
> Sean
>
>

Andrew.


July 01, 2005
In article <da2pcb$4k3$1@digitaldaemon.com>, Andrew Fedoniouk says...
>
>Seems like I didn't get something....
>
>My thought was:
>
>scanf(char[], ...);
>and
>parse(...);
>
>First one used with mandatory format parameter.
>Second - "formatless" parsing.

The way readf works now is that it uses certain defaults if no format strings are specified, but format strings can be used to be more specific:

int i, j; char[] c;
sreadf( "abc 0x1", &c, &i, "x", &j ); // 1
sreadf( "abc 0x1", &c, "%x", &i );    // 2

In 1 above, c will contain 'abc', i will contain '0', and j will contain '1'. In 2, c will contain 'abc', and i will contain '1'.  Format strings can be mixed with input arguments.  I wouldn't mind renaming readf to parse, but I wouldn't want to lose this degree of flexibility.

Another entirely different option for streaming would be to use opCall like Mango does.  I like the way this looks, and it sidesteps the problem with using the address-of operator everywhere.  The only catch with this method is that there's no good way to handle a bidirectional stream.


Sean


July 01, 2005
Sean Kelly wrote:

> The way readf works now is that it uses certain defaults if no format strings
> are specified, but format strings can be used to be more specific:
> 
> int i, j; char[] c;
> sreadf( "abc 0x1", &c, &i, "x", &j ); // 1
> sreadf( "abc 0x1", &c, "%x", &i );    // 2
> 
> In 1 above, c will contain 'abc', i will contain '0', and j will contain '1'.
> In 2, c will contain 'abc', and i will contain '1'.  Format strings can be mixed
> with input arguments.  I wouldn't mind renaming readf to parse, but I wouldn't
> want to lose this degree of flexibility.

It's also a very good match to "writef", which makes it look sensible.
So in my opinion it should keep the name readf, instead of being "parse"

BTW;
I thought that "unformat" was a much better name than sreadf, but that's
a little beside the point... (i.e. std.string.unformat and std.unformat)

The naming was carefully chosen to make the "I" match the (current) "O"
Details: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21692


The only "extra" besides C's scanf is to pass pointers to strings too ?
(otherwise it wasn't able to separate between formats and string params)

Whether it works on FILE* or streams doesn't really "matter" either.
And it still needs TypeInfo for pointer types, in order to work OK...

--anders
« First   ‹ Prev
1 2