www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Input Scanning

reply Max Mayrhofer <swinging_salsero hotmail.com> writes:
Hi all, I have what is I suspect a silly question, but I am having a
total brainfart over this for some reason.  I want to read an
arbitrary amount of floats from user input and then perform some
statistics work on them. For some reason, I can't figure out how to
get it to recognise when the user has stopped entering values.  My
current code is:

void main(string[] args) {
	Stat[] stats;
	foreach (arg; args[1 .. $]) {
		auto newStat = cast(Stat) Object.factory("main." ~
arg);
		enforce(newStat, "Invalid statistics function: " ~
arg);
		stats ~= newStat;
	}
	for (double x; stdin.readf(" %s ", &x) == 1; ) {
		foreach (s; stats) {
			s.accumulate(x);
		}
	}
	foreach (s; stats) {
		s.postprocess();
		writeln(s.result());
	}
}

At the moment it just crashes with a conversion error when invoked,
for example, with:

echo 3 1.6 17 | stats Min Average

I know my problem is the readf, but what would best practice be for
this situation?
Sep 07 2010
parent reply Jonathan M Davis <jmdavisprog gmail.com> writes:
On Tuesday 07 September 2010 09:55:29 Max Mayrhofer wrote:
 Hi all, I have what is I suspect a silly question, but I am having a
 total brainfart over this for some reason.  I want to read an
 arbitrary amount of floats from user input and then perform some
 statistics work on them. For some reason, I can't figure out how to
 get it to recognise when the user has stopped entering values.  My
 current code is:
 
 void main(string[] args) {
 	Stat[] stats;
 	foreach (arg; args[1 .. $]) {
 		auto newStat = cast(Stat) Object.factory("main." ~
 arg);
 		enforce(newStat, "Invalid statistics function: " ~
 arg);
 		stats ~= newStat;
 	}
 	for (double x; stdin.readf(" %s ", &x) == 1; ) {
 		foreach (s; stats) {
 			s.accumulate(x);
 		}
 	}
 	foreach (s; stats) {
 		s.postprocess();
 		writeln(s.result());
 	}
 }
 
 At the moment it just crashes with a conversion error when invoked,
 for example, with:
 
 echo 3 1.6 17 | stats Min Average
 
 I know my problem is the readf, but what would best practice be for
 this situation?

Wouldn't the normal solution be to read in the entire line and then parse it rather than reaing in each value individually? So, wouldn't you use std.stdio.readln() to read the line from stdin and std.conv.parse() to parse out the values? - Jonathan M Davis
Sep 07 2010
parent Max Mayrhofer <swinging_salsero hotmail.com> writes:
Yea of course that does make sense, there ya go :)
Sep 07 2010