www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.stdio is incomplete (missing scanf() replacement)

reply Tyro <ridimz_at yahoo.dot.com> writes:
When I first started learning to program some three- years ago, with D, one of
the major obstacles I faced was the lack of publication/documentation. So I
decided to purchase books about C++ programming and use the examples in D. I
soon found that almost none of the user interaction examples involving string
input could be practiced because scanf() could not properly interact with
D-strings (a.k.a. char[]).

With enough prodding, Pavel Minayev was able to bring us std.stream, which
partially rectified the problem. Then along came Kris, who brought us Mango and
in particular mango.io which, once again, partially rectifies the problem.
Don't get me wrong; these are both great and necessary library and library
facilities for which I am extremely grateful. But the problem still remains.

When I import std.stdio into my program, I expect to have two distinct
functionalities at my disposal: 1) The ability to retrieve information (be it
from file, strings, stdin, or what have you) and 2) The ability to output
information. That by its very nature are the responsibilities of stdio (a
standardized way of performing input and output).
 
To some extent the current stdio module accomplishes both of these
responsibilities. It provides input functionality through the new designed
writef() family of functions. It also provides for output; albeit through C
linkage to the rickety old scanf() function in std.c.stdio.

scanf(), though a versatile function for C programming, does not cut the
mustard for D. We need better. Now how can this be rectified?

Simple: allow out and inout parameters for use in conjunction with variadic
functions.

private import std.stdio;
private import std.stream;

extern (C) int fflush(FILE *stream);

alias std.c.stdio.stdin stdin;
alias std.c.stdio.stdout stdout;

void main() {
  char[] name = "";
  double d = 0.0;
  readf(name,d,name,d);
  writefln(name);
  writefln(d);
}

void readf (out char[] v1,out double v2, ...) {
  fflush(stdout);
  readx (stdin, _arguments, _argptr);
  _argptr -= double.sizeof;
  v2 = *cast(double*)_argptr;
  _argptr -= (char[]).sizeof;
  v1 = *cast(char[]*)_argptr;
  fflush(stdin);
}

void freadf (FILE* fp, ...) {
  readx (fp, _arguments, _argptr);
}
 
void readx (FILE* buf, TypeInfo[] args, inout void* argptr)
{
  foreach(TypeInfo ti; args)
  {
    if (ti is typeid(char))
    {
      writef("Enter a char: ");
      scanf("%c", &*cast(char*)argptr);
      writefln("done: char(",*cast(char*)argptr,")");
      argptr += int.sizeof;
    }
    else if (ti == typeid(double))
    {
      writef("Enter a double: ");
      scanf("%lf", &*cast(double*)argptr);
      writefln("done: double(",*cast(double*)argptr,")");
      argptr += double.sizeof;
    }
    else if (ti == typeid(char[]))
    {
      writef("Enter a string: ");
      char[256] tmp;
      scanf("%s",&tmp);
      int i;
      foreach(int ndx, char c; tmp)
      { if(c == '\0') { i = ndx; break; } }
      *cast(char[]*)argptr = tmp[0 .. i];
      writefln("done: char[](",*cast(char[]*)argptr,")");
      argptr += (char[]).sizeof;
    }
  }
}

As is demonstrated, new values can be passed back trough _argptr, and 
with the out and inout, it would make it that much easier. This will 
help us to develop a more more robust, D-centric scanf function. Thereby 
completely invalidating the statement:

"Who D is Not For
   As a first programming language - Basic or Java is more suitable for 
beginners."

Like it or not. Beginners are using the language. And noting you do or 
say will stop them. So how about we accommodate and more quickly 
acclimatize the to the community?

Andrew Edwards
[acedwards] (at) [ieee] (dot) [org]
Dec 25 2004
next sibling parent Jerry Laws <taoiststarter -nospam-yahoo.com> writes:
Tyro wrote:
[snip]
 "Who D is Not For
   As a first programming language - Basic or Java is more suitable for 
 beginners."
 
 Like it or not. Beginners are using the language. And noting you do or 
 say will stop them. So how about we accommodate and more quickly 
 acclimatize the to the community?
 
 Andrew Edwards
 [acedwards] (at) [ieee] (dot) [org]
Yes, please. I'm looking for a language to "co-learn" with Python, and D with all its power looks like a solid choice, but..... The easier it is for beginners, because everyone is initially, to switch to D, the faster the language and its libraries can evolve. Just my 0.02 Looks like a great lang. to this newbie, I wish it the best.
Dec 25 2004
prev sibling parent "Simon Buchan" <talk n.g> writes:
<snip>
 void readf (out char[] v1,out double v2, ...) {
<big snip> Sorry? I don't get this. What is this supposed to mean? Also, your code is ... odd. (_argptr += int.sizeof in reading char? prompting the user? non-debug confirmation?) Granted, a decent treatment of variadic parameters would be nice. Something along the lines of regular expression semantics? (The syntax would obviosly be far too confusing to meld with D)
Dec 28 2004