July 01, 2005
"Sean Kelly" <sean@f4.ca> wrote in message news:da2r8l$7g1$1@digitaldaemon.com...
> 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

Got it, thanks.

BTW: "%x" will set hex mode for all consequent ints or just for the next arg?

Seems like C++ streams with use of ',' instead of >> ...


>
> 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
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da2bs0$2ptk$1@digitaldaemon.com...
> 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);

I'm not sure what you're getting at exactly but what I currently have
 din.scanf("%s",a)
will read one word and store it in a like scanf used to. The second case
 din.scanf(a,b);
will read two characters and store the first in *a and the second in *b.
Do you mean char[] a and char[] b? The way I have scanf distinguishing
format strings from everything is that a format string is a char[] and
everything else must be a pointer to something. It seems natural, simple and
unambiguous.

> 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.

Good idea! But doesn't streams support printf with old C syntax as well? For symmetry between the two, perhaps you should leave the old scanf as it is and call the new function readf() or something similar instead. That way it won't break any existing code, either. (Whether or not the old printf/scanf should be removed from stream altogether is another discussion :-)

Nick


July 01, 2005
"Nick" <Nick_member@pathlink.com> wrote in message news:da3kbt$19j7$1@digitaldaemon.com...
> 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.
>
> Good idea! But doesn't streams support printf with old C syntax as well?
> For
> symmetry between the two, perhaps you should leave the old scanf as it is
> and
> call the new function readf() or something similar instead. That way it
> won't
> break any existing code, either. (Whether or not the old printf/scanf
> should be
> removed from stream altogether is another discussion :-)
>
> Nick

That's possible but somehow I'd like to keep the name scanf since it's
largely compatible with the existing scanf. Maybe to be unambiguous, though,
the old scanf should be removed and the new one should be called readf and
vreadf. I'd prefer not have both scanf and readf since the code involved is
non-trivial (about 50-100 lines) while printf is a 5 line wrapper around C's
sprintf and is more commonly used than scanf.
Another argument in favor of readf is that if std.stdio ever gets a
read-equivalent to writef it will probably be called readf to avoid name
clashes with scanf.
Hmm. I'm starting to swing over to readf.


July 01, 2005
In article <da2sfm$8ob$1@digitaldaemon.com>, Andrew Fedoniouk says...
>
>
>"Sean Kelly" <sean@f4.ca> wrote in message news:da2r8l$7g1$1@digitaldaemon.com...
>>
>> int i, j; char[] c;
>> sreadf( "abc 0x1", &c, &i, "x", &j ); // 1
>> sreadf( "abc 0x1", &c, "%x", &i );    // 2
>
>Got it, thanks.
>
>BTW: "%x" will set hex mode for all consequent ints or just for the next arg?

Just the next arg.

>Seems like C++ streams with use of ',' instead of >> ...

It's kind of a hybrid.  Internally, the code is basically a pure scanf implementation (as that's what it started as) but now if it doesn't have a format string it checks if the next parameter is one.  If so, it uses it until it's exhausted and if not it supplies a default one for that parameter.  To be identical to writef, the code would have to allow bit values to be parsed as "true/false" if a "%s" format string is supplied.


Sean


July 02, 2005
Ben Hinkle:
>That's possible but somehow I'd like to keep the name scanf since it's
>largely compatible with the existing scanf. Maybe to be unambiguous, though,
>the old scanf should be removed and the new one should be called readf and
>vreadf. I'd prefer not have both scanf and readf since the code involved is
>non-trivial (about 50-100 lines) while printf is a 5 line wrapper around C's
>sprintf and is more commonly used than scanf.
>Another argument in favor of readf is that if std.stdio ever gets a
>read-equivalent to writef it will probably be called readf to avoid name
>clashes with scanf.
>Hmm. I'm starting to swing over to readf.

I think readf goes nicely together with writef, as in "read" and "write" (but then I never liked the name scanf.) Also, it signals to C programmers that it is not a simple wrapper around the C scanf, but a entirely new function. Just my two cents.

Nick


July 02, 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).

I would think passing a buffer to be filled would be fairly common so in my
implementation I made %s, when parsing a char[]*, use any buffer that is
passed in (appending if the buffer was too short) and assigns a slice of the
result when done. For example
  char[] str = new char[128];
  din.readf(&str);
with the input "foobar" will fill str with foobar and set its length to 6.
If str were left uninitialized or if the input were longer than 128 chars
then a new string would be allocated (by appending). If you want to do this
sort of thing in a loop you'd probably want something like
  char[128] buf;
  while (whatever) {
    char[] str = buf; // reuse the full buffer each time
    din.readf(&str);
    // str now is a slice of buf (or a new array if str is too big)
  }


July 02, 2005
In article <da68uh$oph$1@digitaldaemon.com>, Ben Hinkle says...
>
>
>"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).
>
>I would think passing a buffer to be filled would be fairly common so in my implementation I made %s, when parsing a char[]*, use any buffer that is passed in (appending if the buffer was too short) and assigns a slice of the result when done. For example
>  char[] str = new char[128];
>  din.readf(&str);
>with the input "foobar" will fill str with foobar and set its length to 6. If str were left uninitialized or if the input were longer than 128 chars then a new string would be allocated (by appending). If you want to do this sort of thing in a loop you'd probably want something like
>  char[128] buf;
>  while (whatever) {
>    char[] str = buf; // reuse the full buffer each time
>    din.readf(&str);
>    // str now is a slice of buf (or a new array if str is too big)
>  }

But in both these cases you're passing in a pointer (ie. char[]*).  I meant
someting like this:

char[] buf1, buf2;

buf1.length = 100;
readf( buf1, &buf2 );

Even though buf1 conceivably has enough space to store an input string, I am treating it as a format string, because if buf1 needs to be expanded then the new string will not be visible once readf returns.  buf2, by comparison, was passed by reference, so it can be resized as needed and the changes will be preserved.


Sean


July 02, 2005
"Sean Kelly" <sean@f4.ca> wrote in message news:da6k7r$11sk$1@digitaldaemon.com...
> In article <da68uh$oph$1@digitaldaemon.com>, Ben Hinkle says...
>>
>>
>>"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).
>>
>>I would think passing a buffer to be filled would be fairly common so in
>>my
>>implementation I made %s, when parsing a char[]*, use any buffer that is
>>passed in (appending if the buffer was too short) and assigns a slice of
>>the
>>result when done. For example
>>  char[] str = new char[128];
>>  din.readf(&str);
>>with the input "foobar" will fill str with foobar and set its length to 6.
>>If str were left uninitialized or if the input were longer than 128 chars
>>then a new string would be allocated (by appending). If you want to do
>>this
>>sort of thing in a loop you'd probably want something like
>>  char[128] buf;
>>  while (whatever) {
>>    char[] str = buf; // reuse the full buffer each time
>>    din.readf(&str);
>>    // str now is a slice of buf (or a new array if str is too big)
>>  }
>
> But in both these cases you're passing in a pointer (ie. char[]*).  I
> meant
> someting like this:
>
> char[] buf1, buf2;
>
> buf1.length = 100;
> readf( buf1, &buf2 );
>
> Even though buf1 conceivably has enough space to store an input string, I
> am
> treating it as a format string, because if buf1 needs to be expanded then
> the
> new string will not be visible once readf returns.  buf2, by comparison,
> was
> passed by reference, so it can be resized as needed and the changes will
> be
> preserved.

Agreed. My code does the same. The difference I was trying to highlight was the case when buf2 has non-zero length before the call the readf. I got the impression your implementation would not use the passed in buf2 - is that correct? I might have misunderstood that the buffer will be filled.


July 02, 2005
In article <da6l90$12s5$1@digitaldaemon.com>, Ben Hinkle says...
>
>
>"Sean Kelly" <sean@f4.ca> wrote in message news:da6k7r$11sk$1@digitaldaemon.com...
>>
>> But in both these cases you're passing in a pointer (ie. char[]*).  I
>> meant
>> someting like this:
>>
>> char[] buf1, buf2;
>>
>> buf1.length = 100;
>> readf( buf1, &buf2 );
>>
>> Even though buf1 conceivably has enough space to store an input string, I
>> am
>> treating it as a format string, because if buf1 needs to be expanded then
>> the
>> new string will not be visible once readf returns.  buf2, by comparison,
>> was
>> passed by reference, so it can be resized as needed and the changes will
>> be
>> preserved.
>
>Agreed. My code does the same. The difference I was trying to highlight was the case when buf2 has non-zero length before the call the readf. I got the impression your implementation would not use the passed in buf2 - is that correct? I might have misunderstood that the buffer will be filled.

That's essentially correct.  My implementation deals only with dchars and does a UTF conversion if necessary when writing the output string.  So any way you cut it, a temporary dchar buffer is being filled with input chars.  I suppose I could have tried to use the existing buffer instead and perhaps done the UTF conversion a char at a time as data was processed.  Perhaps I'll look into it if I find some time.


Sean


1 2
Next ›   Last »