6

What is the best way in Python 3 to read in multi-line user input when the amount of input is unknown? The multi-line input will be separated by Enter

when I try using

while True:
    line = input()
    if line:
          print(line)
    else:
          break

I receive an EOFError

Then if I change it to a try-catch block

while True:
    line = input()
    try:
          print(line)
    except EOFError:
          break

I still get the EOFError.

Mazzone
  • 401
  • 1
  • 6
  • 21
  • 2
    That's logical, since the error does not occur at printing, but at `input()`. So that should be in the `try`. – Willem Van Onsem Oct 05 '17 at 18:26
  • Are you piping data in from stdin? I've never seen an EOFError from calling `input` but I suppose it's possible. – Adam Smith Oct 05 '17 at 18:27
  • @AdamSmith: yes, if you use `Ctrl+D` in most terminals, this is also seen as termining the stdin. – Willem Van Onsem Oct 05 '17 at 18:30
  • The dupe is one of the most concise, smartest answers out there. – cs95 Oct 05 '17 at 18:35
  • @cᴏʟᴅsᴘᴇᴇᴅ the dupe does not answer the question. As specified in my title I ask specifically for Python 3. The dupe is for Python 2 – Mazzone Oct 06 '17 at 21:58
  • @Mazzone did you not see the part of the answer that addresses python3? – cs95 Oct 07 '17 at 00:17
  • @cᴏʟᴅsᴘᴇᴇᴅ input versus raw_input is used – Mazzone Oct 07 '17 at 01:03
  • @Mazzone That is for python3. What is your issue? – cs95 Oct 07 '17 at 01:28
  • @cᴏʟᴅsᴘᴇᴇᴅ please remove the duplicate tag, this is persistent problem in StackOverflow as explained here: https://www.quora.com/Why-is-Python-unsuitable-as-a-mobile-application-development-language – Mazzone Oct 25 '17 at 19:23

2 Answers2

10

The EOFError occurs when you call input(), not when you test it, nor when you print it. So that means you should put input() in a try clause:

try:
    line = input()
    print(line)
except EOFError:
    break

That being said, if input reads from the standard input channel, you can use it as an iterable:

import sys

for line in sys.stdin:
    print(line, end='')

Since every line now ends with the new line character '\n', we can use end='' in the print function, to prevent print a new line twice (once from the string, once from the print function).

I think the last version is more elegant, since it almost syntactically says that you iterate over the stdin and processes the lines individually.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • But the last line might cause problems, won't it? Mimicking `input()` exactly might be subtle – Elazar Oct 05 '17 at 18:33
  • @Elazar: based on the [documentation](https://docs.python.org/3/library/functions.html#input) of input, it reads from the stdin, strips the new line, and returns that. And raises an `EOFError` in case it has an EOF char. This is afaik the same what the iterator protocol over a `stdin` does (except that it terminates the loop in case of an EOF, and that it does not strip the new line). – Willem Van Onsem Oct 05 '17 at 18:36
0

Break the loop if input is blank,

a = []
while True:
   user_input = input()
   if user_input == '':
     break
   else:
       a.append(int(user_input))
       
print(sum(a))

produces,

3

3

[Program finished]

If you know the range,

x, *z= [int(input()) for _ in range(3)]
print(x + sum(z))

produces,

3
4
5
12

[Program finished] 
Subham
  • 397
  • 1
  • 6
  • 14