digitalmars.D.bugs - [Issue 10467] New: readln problem with CTRL-Z
- d-bugmail puremagic.com (35/38) Jun 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10467
- d-bugmail puremagic.com (26/33) Jun 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10467
- d-bugmail puremagic.com (22/26) Jun 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10467
- d-bugmail puremagic.com (6/16) Jun 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10467
- d-bugmail puremagic.com (20/52) Jun 25 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10467
http://d.puremagic.com/issues/show_bug.cgi?id=10467 Summary: readln problem with CTRL-Z Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: bearophile_hugs eml.cc import std.stdio, std.string; void main() { while (true) { write("Input: "); string guess = readln.strip; if (guess == "1") break; } } On Windows if I run that little program and I insert "1" the program terminates normally:dmd -run temp.dInput: 1 If at the input promtp I give a Ctrl-C it breaks the program:dmd -run temp.dInput: ^C If at the input prompt I give a Ctrl-Z the while loop seems to go in an infinite loop:dmd -run temp.dInput: ^Z Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: ... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10467 monarchdodra gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |monarchdodra gmail.comIf at the input prompt I give a Ctrl-Z the while loop seems to go in an infinite loop:Just for the record, what *would* the correct behavior be? The stream is at eof, so stdin has no need to wait for user input, and if you ask for a line, you get "" ... A "correct" program would have either: while (stdin.isOpen && !stdin.eof && !stdin.error) //Meh... Or... string s; while ((s = stdin.readln(line)).length) //very good! Or... char[] line; while (stdin.readln(line)) //very good! For the record, I don't think readln can throw an exception, since the "common semantic" is "read lines until the read fails, then check it failed because you have reached eof"... So... yeah... Doesn't seem like a bug to me, just a program that wasn't designed to handle stdin's eof... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------dmd -run temp.dInput: ^Z Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: ...
Jun 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10467Just for the record, what *would* the correct behavior be?An equivalent Python2.6 program: while True: guess = raw_input("Input: ").strip() if guess == "1": break This is how Python behaves here (inputs are 1, CTRL-C and CTRL-Z):temp.pyInput: 1temp.pyInput: Traceback (most recent call last): File "\temp.py", line 2, in <module> guess = raw_input("Input: ").strip() KeyboardInterrupttemp.pyInput: ^Z Traceback (most recent call last): File "\temp.py", line 2, in <module> guess = raw_input("Input: ").strip() EOFError -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10467 Elsewhere monarch_dodra adds some more comments on this topic and a link:I don't think this is a bug (I replied on the bug report): terminating the stream doesn't mean terminating the program, and if the program doesn't know how to handle a closed/eof/error'd stdin, it will just loop... This FAQ link explains it pretty well for C++, which is pretty much the same thing as in D: http://www.parashift.com/c++-faq/stream-input-failure.html (the next few points are relevant too). We could argue the design isn't optimal, yes, but it's not bugged.-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10467I'm noticing D's readln doesn't quite have the same semantics as C++'s: In C++, getline will keep reading until it *can* read at least a single non empty line, trying again if it reads an empty line. This means that you can't know if you'll succeed unless you try. getline explicitly returns the state of the stream, so you can test the return status of getline. D's getline, on the other hand, returns empty lines. This means there is no real way to check for success, unless an exception was thrown, or the stream is in an error state. This means the interface is kind of crummy, since it claims: "returns: 0 for end of file, otherwise number of characters read": which sucks, since it can succeed if 0 characters were read... Also, D's readln says "StdioException on I/O error". So after a second though, I think you are right, and Python's "throw for reads of EOF" is not only safer and better, but also works, and is the *documented behavior*... too bad we didn't have this for C++ :'( -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Just for the record, what *would* the correct behavior be?An equivalent Python2.6 program: while True: guess = raw_input("Input: ").strip() if guess == "1": break This is how Python behaves here (inputs are 1, CTRL-C and CTRL-Z):temp.pyInput: 1temp.pyInput: Traceback (most recent call last): File "\temp.py", line 2, in <module> guess = raw_input("Input: ").strip() KeyboardInterrupttemp.pyInput: ^Z Traceback (most recent call last): File "\temp.py", line 2, in <module> guess = raw_input("Input: ").strip() EOFError
Jun 25 2013