www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Equivalent of scanf

reply Michael Koehmstedt <mkoehmstedt runner.csub.edu> writes:
I'm having trouble figuring out how to do formatted console input, something
like C scanf() or C++ templated stream input. Unfortunately, console input
isn't covered in much detail in TDPL book. There doesn't appear to be much
discussion about the standard library at all, which was a bit disappointing.

But anyway, what different ways are there to properly do input from the
console? Fetching a string with readln() is easy enough, but how could I
fetch, say, an integer value? Conversely, what is the preferred method for
converting string into integer or floating point values?

Thanks,
Michael
Jul 17 2010
next sibling parent torhu <no spam.invalid> writes:
On 18.07.2010 00:41, Michael Koehmstedt wrote:
 I'm having trouble figuring out how to do formatted console input, something
 like C scanf() or C++ templated stream input. Unfortunately, console input
 isn't covered in much detail in TDPL book. There doesn't appear to be much
 discussion about the standard library at all, which was a bit disappointing.

 But anyway, what different ways are there to properly do input from the
 console? Fetching a string with readln() is easy enough, but how could I
 fetch, say, an integer value? Conversely, what is the preferred method for
 converting string into integer or floating point values?

The standard library (Phobos) is getting overhauled, which is probably why there's not a lot of detail about it in the book. It's still quite limited and buggy. Up until now, most real D work has probably been done using D1 and the Tango library. There's a scanf implementation in the works, but it's not released yet. You can probably get by with the to() and parse() functions in std.conv. C's isdigit() will probably come in handy too, it's defined in core.stdc.ctype.
Jul 17 2010
prev sibling next sibling parent reply Jonathan M Davis <jmdavisprog gmail.com> writes:
On Saturday 17 July 2010 15:41:14 Michael Koehmstedt wrote:
 I'm having trouble figuring out how to do formatted console input,
 something like C scanf() or C++ templated stream input. Unfortunately,
 console input isn't covered in much detail in TDPL book. There doesn't
 appear to be much discussion about the standard library at all, which was
 a bit disappointing.
 
 But anyway, what different ways are there to properly do input from the
 console? Fetching a string with readln() is easy enough, but how could I
 fetch, say, an integer value? Conversely, what is the preferred method for
 converting string into integer or floating point values?
 
 Thanks,
 Michael

Parsing strings like that isn't something that I've done much of lately, so I don't know what the best way to do it in D is. However, std.conv has essentially what you're looking for. For most conversions, just use to!T() - e.g. to!int(str) will convert the string str into an int and to!string(i) will convert the integer i to a string. For more complicated parsing, there's parse!T() which does essentially the same thing except that instead of converting the whole string, it only converts the portion which makes sense and leaves the rest. e.g. string test = "123 \t 76.14"; auto a = parse!(uint)(test); assert(a == 123); assert(test == " \t 76.14"); So, with multiple calls to parse, you can parse the string. I'm not aware of a way to do it in manner like sscanf though, where you parse it all in one command. Worse comes to worse, if you really want that, you can always use C's sscanf and it'll work. TDPL purposely didn't touch on Phobos much. One reason for this is because it was focusing on the language itself rather than whatever libraries there might be. The other main reason, as I understand it, is that Phobos has been in too much flux to have put in TDPL. A lot of work has been done on Phobos in the past few months, and TDPL was already turned in to the editor. And a lot of work continues to be done on Phobos. So, anything that was put in TPDL on Phobos would either have constrained Phobos so that it couldn't change when it needed to or would have made it so that TDPL didn't match Phobos - either that or we would have had to wait longer for TDPL. - Jonathan M Davis
Jul 17 2010
parent reply Michael Koehmstedt <mkoehmstedt runner.csub.edu> writes:
Thanks for the informative reply.

I am getting a run-time error with to!int(str). Apparently to!() seems to only
support one-way converting other types to strings. That is part of the reason
why
I was getting so confused in figuring out how to read in an integer value. But
you
guys pointed me towards parse!() and that does work with string->int.

So there is no scanf equivalent, but there is also nothing similar to C++ cin
with
the << operator?

And as for Phobos not being included much in TDPL, makes sense. I hope they
include a reference section on it in the 2nd edition after Phobos is stabilized.
That would make the book near perfect imo.
Jul 17 2010
next sibling parent Michael Koehmstedt <mkoehmstedt runner.csub.edu> writes:
== Quote from Michael Koehmstedt (mkoehmstedt runner.csub.edu)'s article
 So there is no scanf equivalent, but there is also nothing similar to C++ cin
with
 the << operator?

I meant the >> operator, of course. *slaps forehead*
Jul 17 2010
prev sibling next sibling parent torhu <no spam.invalid> writes:
On 18.07.2010 01:21, Michael Koehmstedt wrote:
<snip>
 So there is no scanf equivalent, but there is also nothing similar to C++ cin
with
 the<<  operator?

Equivalents of those are available in std.stream and std.cstream, but those modules will probably go away in a while.
Jul 17 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisprog gmail.com> writes:
On Saturday 17 July 2010 16:35:11 torhu wrote:
 On 18.07.2010 01:21, Michael Koehmstedt wrote:
 <snip>
 
 So there is no scanf equivalent, but there is also nothing similar to C++
 cin with the<<  operator?

Equivalents of those are available in std.stream and std.cstream, but those modules will probably go away in a while.

We'll be getting new streams which are range based which may or may not use the name std.stream, but the current implementation is certainly going away. Like a number in things in Phobos right now, it's being updated and replaced with something better. Phobos is evolving for the better, and it's great to see that it's finally starting to come together. - Jonathan M Davis
Jul 17 2010
prev sibling parent reply Michael Koehmstedt <mkoehmstedt runner.csub.edu> writes:
I am doing this and it is throwing an exception.

string d = readln( );
int i = to!int( d );

I tried

string d = "50";
int i = to!int( d );

and that worked ok.
Jul 18 2010
parent Michael Koehmstedt <mkoehmstedt runner.csub.edu> writes:
Thanks again Jonathan, that was informative and helpful. I have enough info now
to
get what I want done without having to resort to using the standard C library.

According to Philippe's post, D's scanf (readf) should be included in the next
release. Excellent =D
Jul 18 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisprog gmail.com> writes:
On Saturday 17 July 2010 16:21:04 Michael Koehmstedt wrote:
 Thanks for the informative reply.
 
 I am getting a run-time error with to!int(str). Apparently to!() seems to
 only support one-way converting other types to strings. That is part of
 the reason why I was getting so confused in figuring out how to read in an
 integer value. But you guys pointed me towards parse!() and that does work
 with string->int.

Hmm... to!int(str) seems to be working for me. The issue is probably that when doing such a conversion, the _whole_ string must be convertable. So, no extra whitespace or whatnot. If you're looking to take multiple values out of a particular string or you might have whitespace in it, parse() is a better choice. But to() should work just fine as long as the string is exactly convertable to the type. As I understand it, to() should be able to convert pretty much anything to anything as long as the type has the appropriate conversion functions defined. - Jonathan M Davis
Jul 17 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisprog gmail.com> writes:
On Sunday 18 July 2010 02:58:59 Michael Koehmstedt wrote:
 I am doing this and it is throwing an exception.
 
 string d = readln( );
 int i = to!int( d );
 
 I tried
 
 string d = "50";
 int i = to!int( d );
 
 and that worked ok.

That would be because readln() was likely giving you more than just an int. All it would take would be a character of whitespace or a newline (there's a decent chance that readln() returns a string that ends in a newline) and to!int() would throw. So, if you're dealing with strings which may include stuff other than what you're actually trying to convert to, then parse!T() would likely be a better choice. You can also use std.string.strip() on a string to get rid of any whitespace on its ends if you're sure that it's only a number with whitespace. If you really feel that we should have a version of scanf() for D, then you can always open up a bug report with enhancement request as the severity. If one isn't in the works, it might encourage it, and if one is already in the works, it might make it happen faster (since there would be an obvious desire for it plus there would be a bug report as a reminder). - Jonathan M Davis
Jul 18 2010
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--001636c5b7de397f21048ba883d2
Content-Type: text/plain; charset=ISO-8859-1

Andrei checked readf in a few days ago:

http://www.dsource.org/projects/phobos/changeset/1721

So, it should be in the next release (end of July/beginning of August?)
Would readf help you?

For files, there is also std.file.slurp if you know the way your file is
formatted:

http://digitalmars.com/d/2.0/phobos/std_file.html#slurp

Before you ask, the name comes from Perl :-)



Philippe

--001636c5b7de397f21048ba883d2
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Andrei checked readf in a few days ago:<br><br><a href=3D"http://www.dsourc=
e.org/projects/phobos/changeset/1721" target=3D"_blank">http://www.dsource.=
org/projects/phobos/changeset/1721</a><br><br>So, it should be in the next =
release (end of July/beginning of August?)<br>
Would readf help you?<br><br>For files, there is also std.file.slurp if you=
 know the way your file is formatted:<br><br><a href=3D"http://digitalmars.=
com/d/2.0/phobos/std_file.html#slurp">http://digitalmars.com/d/2.0/phobos/s=
td_file.html#slurp</a><br>
<br>Before you ask, the name comes from Perl :-)<br><br><br><br>Philippe<br=
<br><br><br>

--001636c5b7de397f21048ba883d2--
Jul 18 2010