-
-
Notifications
You must be signed in to change notification settings - Fork 705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
readln problem with CTRL-Z #9986
Labels
Comments
monarchdodra commented on 2013-06-24T14:57:58Z(In reply to comment #0)
> If at the input prompt I give a Ctrl-Z the while loop seems to go in an
> infinite loop:
>
> >dmd -run temp.d
> Input: ^Z
> Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input:
> Input: Input: Input: Input: Input: ...
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... |
bearophile_hugs commented on 2013-06-24T15:20:18Z(In reply to comment #1)
> 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.py
Input: 1
>temp.py
Input: Traceback (most recent call last):
File "\temp.py", line 2, in <module>
guess = raw_input("Input: ").strip()
KeyboardInterrupt
>temp.py
Input: ^Z
Traceback (most recent call last):
File "\temp.py", line 2, in <module>
guess = raw_input("Input: ").strip()
EOFError |
bearophile_hugs commented on 2013-06-24T15:38:23ZElsewhere 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. |
monarchdodra commented on 2013-06-25T00:12:41Z(In reply to comment #2)
> (In reply to comment #1)
>
> > 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.py
> Input: 1
>
> >temp.py
> Input: Traceback (most recent call last):
> File "\temp.py", line 2, in <module>
> guess = raw_input("Input: ").strip()
> KeyboardInterrupt
>
> >temp.py
> Input: ^Z
> Traceback (most recent call last):
> File "\temp.py", line 2, in <module>
> guess = raw_input("Input: ").strip()
> EOFError
I'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++ :'( |
bugzilla (@WalterBright) commented on 2019-11-12T18:38:14ZOn linux, the program is just suspended when entering ^Z, as expected, and can be continued by entering "fg". Looks to me a windows only bug. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bearophile_hugs reported this on 2013-06-24T14:12:19Z
Transfered from https://issues.dlang.org/show_bug.cgi?id=10467
CC List
Description
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.d Input: 1 If at the input promtp I give a Ctrl-C it breaks the program: >dmd -run temp.d Input: ^C If at the input prompt I give a Ctrl-Z the while loop seems to go in an infinite loop: >dmd -run temp.d Input: ^Z Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: Input: ...The text was updated successfully, but these errors were encountered: