www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - readf for the novice

reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Since cstream is deprecated and stdio.readf is finally available with 
2.048, I started modifying my D book by replacing code like

     T var;
     din.readf(&var);

with

     T var;
     readf("%s", &var);


1) I couldn't go far, because stdio.readf does not ignore whitespace and 
code like the following fail:

     int i;
     int j;

     readf("%s", &i);
     readf("%s", &j);

When the input is

42 43

the output is

std.conv.ConvError: std.conv(1070): Can't convert value 
`LockingTextReader(File(807637C),  )' of type LockingTextReader to type int
[...]

Is that by design? Should the users strip the input themselves?


2) This is not a show stopper, but having to provide a format string for 
simple value input is unnecessary. It makes D less suitable for 
programming novices. (I see D very easy for novices in general, 
especially compared to C and C++.)


3) We need a simple way of reading values from stdin if only for the novice.

Another solution is using string.strip and conv.parse:

     auto line = strip(stdin.readln());
     auto i = parse!int(line);
     auto d = parse!double(line);

but that requires importing std.string and std.conv in addition to 
std.stdio. Also, with that, both of the values must be on the same line.

A novice should be able to read as simple as

     auto d = read!double();
     auto i = read!int();

Ignoring stripping whitespace, read can be implemented like this:

T read(T)()
{
     T value;
     readf("%s", &value);
     return value;
}

Actually stream.readf's signature was also nice. Can we do the same with 
stdio.readf?

   readf(&v0, &v1, &v2);

Ali
Aug 16 2010
next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Ali Çehreli Wrote:

 Since cstream is deprecated and stdio.readf is finally available with 
 2.048, I started modifying my D book by replacing code like
 
      T var;
      din.readf(&var);
 
 with
 
      T var;
      readf("%s", &var);
 
 
 1) I couldn't go far, because stdio.readf does not ignore whitespace and 
 code like the following fail:
 
      int i;
      int j;
 
      readf("%s", &i);
      readf("%s", &j);
 
 When the input is
 
 42 43
 
 the output is
 
 std.conv.ConvError: std.conv(1070): Can't convert value 
 `LockingTextReader(File(807637C),  )' of type LockingTextReader to type int
 [...]
 
 Is that by design? Should the users strip the input themselves?
It looks like a bug to me.
 2) This is not a show stopper, but having to provide a format string for 
 simple value input is unnecessary. It makes D less suitable for 
 programming novices. (I see D very easy for novices in general, 
 especially compared to C and C++.)
Since D has TypeInfo for variadic arguments, you're right that a format string shouldn't often be necessary.
 3) We need a simple way of reading values from stdin if only for the novice.
 
 Another solution is using string.strip and conv.parse:
 
      auto line = strip(stdin.readln());
      auto i = parse!int(line);
      auto d = parse!double(line);
 
 but that requires importing std.string and std.conv in addition to 
 std.stdio. Also, with that, both of the values must be on the same line.
 
 A novice should be able to read as simple as
 
      auto d = read!double();
      auto i = read!int();
Seems like a good idea to me.
Aug 16 2010
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Sean Kelly wrote:
 Ali Çehreli Wrote:
      int i;
      int j;

      readf("%s", &i);
      readf("%s", &j);

 When the input is

 42 43

 the output is

 std.conv.ConvError: std.conv(1070): Can't convert value
 `LockingTextReader(File(807637C),  )' of type LockingTextReader to 
type int
 [...]

 Is that by design? Should the users strip the input themselves?
It looks like a bug to me.
Opened http://d.puremagic.com/issues/show_bug.cgi?id=4656 Thank you, Ali
Aug 16 2010
prev sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Ali Çehreli Wrote:

 A novice should be able to read as simple as
 
      auto d = read!double();
      auto i = read!int();
 
 Ignoring stripping whitespace, read can be implemented like this:
 
 T read(T)()
 {
      T value;
      readf("%s", &value);
      return value;
 }
 
 Ali
I created a similar function for my own use. I used a question answer style: auto age = userInput!int("Please Enter you age"); It is meant only to work with stdin and allows for some very nice extension functionality. For example Yes/No questions are possible: if(userInput!bool("Do you want to continue?")) { ... } I then added some other functions: auto outputFolder = pathLocation("Where you do want to place the output?"); auto color = menu!string("What color would you like to use?", ["Blue", "Green"]); Using pathLocation will verify that the folder/file exists before returning (maybe creating the path could be an option). And menu will display the array with numbers for selection; the input accepted is a integer or string and will return an integer or string depending on the request (default int). If any of these seem common enough I'd be willing to clean them up and try to make them Range friendly. I also have a function that takes a bool delegate which will continually ask for input and validates the answer against the delegate before returning.
Aug 17 2010
parent reply Mafi <mafi example.org> writes:
Am 17.08.2010 19:10, schrieb Jesse Phillips:
 Ali �ehreli Wrote:

 A novice should be able to read as simple as

       auto d = read!double();
       auto i = read!int();

 Ignoring stripping whitespace, read can be implemented like this:

 T read(T)()
 {
       T value;
       readf("%s",&value);
       return value;
 }

 Ali
I created a similar function for my own use. I used a question answer style: auto age = userInput!int("Please Enter you age"); It is meant only to work with stdin and allows for some very nice extension functionality. For example Yes/No questions are possible: if(userInput!bool("Do you want to continue?")) { ... } I then added some other functions: auto outputFolder = pathLocation("Where you do want to place the output?"); auto color = menu!string("What color would you like to use?", ["Blue", "Green"]); Using pathLocation will verify that the folder/file exists before returning (maybe creating the path could be an option). And menu will display the array with numbers for selection; the input accepted is a integer or string and will return an integer or string depending on the request (default int). If any of these seem common enough I'd be willing to clean them up and try to make them Range friendly. I also have a function that takes a bool delegate which will continually ask for input and validates the answer against the delegate before returning.
That sounds really cool. Having things like this in the std lib would allow you to write great consistent utilities with simple and short code. If such functions will ever get into phobos (what I really hope), they should get their own module. What do you thinke about 'std.interact'? Anyways, sounds great! Mafi
Aug 17 2010
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Mafi Wrote:

 That sounds really cool. Having things like this in the std lib would 
 allow you to write great consistent utilities with simple and short 
 code. If such functions will ever get into phobos (what I really hope), 
 they should get their own module. What do you thinke about 
 'std.interact'? Anyways, sounds great!
 
 Mafi
Is there anything you would consider adding? I guess I'll make the needed changes and submit it for review. I named the module cmdln.feedback I never really thought that a great fit, but I can agree it really shouldn't be in std.stdio.
Aug 17 2010
parent Andrej Mitrovic <andrej.mitrovich test.com> writes:
Those look really nice, they could especially be used in tutorials. I'm
replicating some D1 examples from the dsource page to be D2 compatible, and I
could add a bunch of more D2 examples as well. 

I'd be willing to write some tutorials for these if they get their way into
Phobos.

Jesse Phillips Wrote:

 Mafi Wrote:
 
 That sounds really cool. Having things like this in the std lib would 
 allow you to write great consistent utilities with simple and short 
 code. If such functions will ever get into phobos (what I really hope), 
 they should get their own module. What do you thinke about 
 'std.interact'? Anyways, sounds great!
 
 Mafi
Is there anything you would consider adding? I guess I'll make the needed changes and submit it for review. I named the module cmdln.feedback I never really thought that a great fit, but I can agree it really shouldn't be in std.stdio.
Sep 06 2010