digitalmars.D.learn - Smartest way to read a number?
- Fabian (37/37) Nov 10 2011 Hey guys.
- Tobias Brandt (12/49) Nov 10 2011 import std.stdio;
- Fabian (1/1) Nov 10 2011 Thanks a lot. That's exactly what I was searching for.
- Kai Meyer (45/101) Nov 10 2011 I don't get the exception on Linux after a new line, I have to wait
- Tobias Brandt (7/115) Nov 10 2011 Yes, you are right. You can make it work by changing to line buffering:
- Andrej Mitrovic (3/3) Nov 10 2011 This: https://github.com/he-the-great/JPDLibs/tree/cmdln/cmdln
- Fabian (2/5) Nov 10 2011 Thank you. :)
- Jonathan M Davis (10/53) Nov 10 2011 parse already throws an exception if it can't parse anything. There's no...
- Fabian (1/1) Nov 10 2011 Ok - Good to know. Thank you ;)
Hey guys. I just want to write a few console applications. Usualy I have to read numbers to calculate some values. But what's the smartest way to read and convert the input? I've coded these lines: import std.stdio, std.string, std.conv; T readNumber(T)() { string buffer; stdin.readln(buffer); buffer = chomp(buffer); if(isNumeric(buffer)) { return parse!T(buffer); } else { throw new Exception("Input is not a number!"); } } void main() { try { int n = readNumber!int(); writeln(n); float f = readNumber!float(); writeln(f); } catch(Exception e) { writeln(e.msg); } } Can I use that function or is there a cleaner way to do this job? Greetings Fabian
Nov 10 2011
import std.stdio; T readNumber(T)() { T result; stdin.readf("%s", &result); return result; } Throws a ConvException if the input string wasn't in the right format. On 10 November 2011 22:48, Fabian <talk2fab online.de> wrote:Hey guys. I just want to write a few console applications. Usualy I have to read nu=mbersto calculate some values. But what's the smartest way to read and convert=theinput? I've coded these lines: import std.stdio, std.string, std.conv; T readNumber(T)() { =A0 =A0 =A0 =A0string buffer; =A0 =A0 =A0 =A0stdin.readln(buffer); =A0 =A0 =A0 =A0buffer =3D chomp(buffer); =A0 =A0 =A0 =A0if(isNumeric(buffer)) =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return parse!T(buffer); =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0else =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0throw new Exception("Input is not a number=!");=A0 =A0 =A0 =A0} } void main() { =A0 =A0 =A0 =A0try =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int n =3D readNumber!int(); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0writeln(n); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0float f =3D readNumber!float(); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0writeln(f); =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0catch(Exception e) =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0writeln(e.msg); =A0 =A0 =A0 =A0} } Can I use that function or is there a cleaner way to do this job? Greetings Fabian
Nov 10 2011
Thanks a lot. That's exactly what I was searching for.
Nov 10 2011
I don't get the exception on Linux after a new line, I have to wait until EOF, which is typically the end of the program if reading from STDIN. Not very useful. import std.stdio; T readNumber(T)() { T result; stdin.readf("%s", &result); return result; } void main() { try { int n = readNumber!int(); writeln(n); float f = readNumber!float();; writeln(f); } catch(Exception e) { writeln(e.msg); } } Sample execution: ----------------------- [kai.meyer kai-rhel6 D]$ dmd -run readnum.d a 1 1.2 ** I hit Ctrl-D here, so this line isn't part of the output *** std.conv(1157): Can't convert value `a 1 1.2 ' of type LockingTextReader to type int ----------------------- Or if you prefer with out my terminal echoing my input: ----------------------- [kai.meyer kai-rhel6 D]$ echo -e 'a\n1\n1.2\n' | dmd -run readnum.d std.conv(1157): Can't convert value `a 1 1.2 ' of type LockingTextReader to type int ---------------------- On 11/10/2011 02:58 PM, Tobias Brandt wrote:import std.stdio; T readNumber(T)() { T result; stdin.readf("%s",&result); return result; } Throws a ConvException if the input string wasn't in the right format. On 10 November 2011 22:48, Fabian<talk2fab online.de> wrote:Hey guys. I just want to write a few console applications. Usualy I have to read numbers to calculate some values. But what's the smartest way to read and convert the input? I've coded these lines: import std.stdio, std.string, std.conv; T readNumber(T)() { string buffer; stdin.readln(buffer); buffer = chomp(buffer); if(isNumeric(buffer)) { return parse!T(buffer); } else { throw new Exception("Input is not a number!"); } } void main() { try { int n = readNumber!int(); writeln(n); float f = readNumber!float(); writeln(f); } catch(Exception e) { writeln(e.msg); } } Can I use that function or is there a cleaner way to do this job? Greetings Fabian
Nov 10 2011
Yes, you are right. You can make it work by changing to line buffering: stdin.setvbuf(null, _IOLBF); But at that point, another solution (like using std.conv.to) is probably the better choice. On 10 November 2011 23:40, Kai Meyer <kai unixlords.com> wrote:I don't get the exception on Linux after a new line, I have to wait until EOF, which is typically the end of the program if reading from STDIN. Not very useful. import std.stdio; T readNumber(T)() { =A0 =A0T result; =A0 =A0stdin.readf("%s", &result); =A0 =A0return result; } void main() { =A0 =A0try =A0 =A0{ =A0 =A0 =A0 =A0int n =3D readNumber!int(); =A0 =A0 =A0 =A0writeln(n); =A0 =A0 =A0 =A0float f =3D readNumber!float();; =A0 =A0 =A0 =A0writeln(f); =A0 =A0} =A0 =A0catch(Exception e) =A0 =A0{ =A0 =A0 =A0 =A0writeln(e.msg); =A0 =A0} } Sample execution: ----------------------- [kai.meyer kai-rhel6 D]$ dmd -run readnum.d a 1 1.2 ** I hit Ctrl-D here, so this line isn't part of the output *** std.conv(1157): Can't convert value `a 1 1.2 ' of type LockingTextReader to type int ----------------------- Or if you prefer with out my terminal echoing my input: ----------------------- [kai.meyer kai-rhel6 D]$ echo -e 'a\n1\n1.2\n' | dmd -run readnum.d std.conv(1157): Can't convert value `a 1 1.2 ' of type LockingTextReader to type int ---------------------- On 11/10/2011 02:58 PM, Tobias Brandt wrote:rtimport std.stdio; T readNumber(T)() { =A0 =A0 T result; =A0 =A0 stdin.readf("%s",&result); =A0 =A0 return result; } Throws a ConvException if the input string wasn't in the right format. On 10 November 2011 22:48, Fabian<talk2fab online.de> =A0wrote:Hey guys. I just want to write a few console applications. Usualy I have to read numbers to calculate some values. But what's the smartest way to read and conve=er!");the input? I've coded these lines: import std.stdio, std.string, std.conv; T readNumber(T)() { =A0 =A0 =A0 =A0string buffer; =A0 =A0 =A0 =A0stdin.readln(buffer); =A0 =A0 =A0 =A0buffer =3D chomp(buffer); =A0 =A0 =A0 =A0if(isNumeric(buffer)) =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return parse!T(buffer); =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0else =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0throw new Exception("Input is not a numb==A0 =A0 =A0 =A0} } void main() { =A0 =A0 =A0 =A0try =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int n =3D readNumber!int(); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0writeln(n); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0float f =3D readNumber!float(); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0writeln(f); =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0catch(Exception e) =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0writeln(e.msg); =A0 =A0 =A0 =A0} } Can I use that function or is there a cleaner way to do this job? Greetings Fabian
Nov 10 2011
This: https://github.com/he-the-great/JPDLibs/tree/cmdln/cmdln The HTML docs explain how to use it. Not mine, but I think this would be a sweet addition to Phobos imo.
Nov 10 2011
Andrej Mitrovic wrote:This: https://github.com/he-the-great/JPDLibs/tree/cmdln/cmdln The HTML docs explain how to use it. Not mine, but I think this would be a sweet addition to Phobos imo.Thank you. :)
Nov 10 2011
On Thursday, November 10, 2011 13:48 Fabian wrote:Hey guys. I just want to write a few console applications. Usualy I have to read numbers to calculate some values. But what's the smartest way to read and convert the input? I've coded these lines: import std.stdio, std.string, std.conv; T readNumber(T)() { string buffer; stdin.readln(buffer); buffer = chomp(buffer); if(isNumeric(buffer)) { return parse!T(buffer); } else { throw new Exception("Input is not a number!"); } } void main() { try { int n = readNumber!int(); writeln(n); float f = readNumber!float(); writeln(f); } catch(Exception e) { writeln(e.msg); } } Can I use that function or is there a cleaner way to do this job?parse already throws an exception if it can't parse anything. There's no need to call isNumeric and throw an exception yourself. However, if you want to guarantee that the whole string is a valid number instead of just the beginning (parse parses as much as it can, leaving what it can't in the string, and throwing if it couldn't parse anything), then use std.conv.to. It requires that the string be _exactly_ a number (no whitespace or extraneous characters). It also doesn't consume the string at all (since it's converting all or nothing). - Jonathan M Davis
Nov 10 2011