-1

I have the following code which reads txt file.

def get_line(filepath):
    f = open(filepath, "r")      
    while True:
      line = f.readline()     
      print(line)      
    f.close()

print ("Start...")
get_line("/path/to/file/textfile.txt")
print ("Stop...")

The code runs without the "while" loop. Once I add the while loop, the terminal just displays a black screen with no error messages and the program runs continiously. Why does this happen?

A.Sim
  • 91
  • 1
  • 10
  • 3
    If you have `True` as a `while` condition, then you are going to need a `break` statement somewhere or else your loop will never terminate. – jjramsey Oct 25 '22 at 18:30
  • 2
    you should check the proper way to read a file line by line https://stackoverflow.com/a/3277516/15649230 – Ahmed AEK Oct 25 '22 at 18:31

5 Answers5

1

f.readline() on a file open in text mode returns the empty string when it reaches the end of the file; the black screen is the infinite series of prints that produce a newline and nothing else.

You don't want a while loop for this case generally; the Pythonic solution is:

def get_line(filepath):
    with open(filepath, "r") as f:  # Use with to manage, so manual close not needed
        for line in f:   # Files are iterables of their lines
            print(line)  # Change to print(line, end='') to avoid added blank lines
                         # or use sys.stdout.write(line)

Or if you must use a while:

def get_line(filepath):
    with open(filepath, "r") as f:
        # Loop ends when line ends up empty
        # Relies on 3.8+'s assignment expression, aka walrus operator
        while line := f.readline():
            print(line)

The pre-walrus version of the while loop approach would be:

        while True:
            line = f.readline()
            if not line:
                break
            print(line)

But in practice, the for loop approach is almost always what you want.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

If you need to read everything inside of that text file, you don't need to use while True. You are not giving it a way to get out of that loop. This should work as well:

with open('/path/to/file/textfile.txt) as f:
    lines = f.read()
    print(lines)

This does pretty much same thing you want as well!

BishwashK
  • 183
  • 9
0

You are reading the file one line at a time in each iteration in the while loop. After reading all of the lines, you reach the end of the file. There is no more data/lines to read, what happens next? .readline() will return empty string.

Since the program runs fast enough, you probably won't see the lines of the file which actually have been loaded but are above of the empty lines. So the black screen is because of that. Blank lines immediately fill the screen.

Assuming you have 4-5 lines in your text file, run this to see this in action:

from time import sleep


def get_line(filepath):
    f = open(filepath, "r")
    while True:
        line = f.readline()
        print(repr(line), flush=True)
        sleep(0.5)
    f.close()


print("Start...")
get_line("text.txt")
print("Stop...")

I added repr() so that you can see the empty strings and sleep(0.5) so that you could see what's going on.

S.B
  • 13,077
  • 10
  • 22
  • 49
  • 1
    Depending on how they're running the code, they may want to change `print(repr(line))` to `print(repr(line), flush=True)`; in pseudo-terminals where `stdout` ends up block-buffered, not line-buffered, the `flush=True` argument will ensure the output still displays promptly (instead of waiting for several seconds before a whole bunch of lines appear at once, then waiting several more seconds, etc.). – ShadowRanger Oct 25 '22 at 18:47
0

You need check eof of a file, otherwise it will run forever until shutdown your computer.

For instance:

    def get_line(filepath):
    f = open(filepath, "r")      
    while True:
      line = f.readline()     
      print(line)
      if not line:
        print('line is at the eof')     
        break
    f.close()
    print ("Start...")
    get_line("A.txt")
    print ("Stop...")
Manh Do
  • 111
  • 8
  • `if len(line) == 0:` is better as just `if not line:`, see [PEP8 programming recommendations](https://peps.python.org/pep-0008/#programming-recommendations) under "For sequences, (strings, lists, tuples), use the fact that empty sequences are false" – ShadowRanger Oct 25 '22 at 18:46
  • tks,I'm trying to illustrate it more clearly. – Manh Do Oct 25 '22 at 18:48
-1

The True will produce an infinite loop. Try this instead

def get_line(filepath):                                                                                 
   with open(filepath, "r") as f:                                                                       
       for line in f.readlines():                                                                       
           print(line) 
JustLearning
  • 1,435
  • 1
  • 1
  • 9
  • Agh, no! `for line in f.readlines():` is almost always wrong; it requires slurping the whole file into memory as a `list` before it can even begin iterating, meaning your code only works for small files (and it's slower to get going than it needs to be even for them). `.readlines()` is the Devil, you almost always want just `for line in f:`, since the latter reads lazily, avoiding the cost of slurping the whole file and cutting it up into a `list` of lines. Please don't teach bad habits to newbies! – ShadowRanger Oct 25 '22 at 18:38