Search code examples
pythonpython-2.xline-endings

Only the last line of a multiline file / string is printed


I searched a bit on Stack Overflow and stumbled on different answers but nothing fitted for my situation...

I got a map.txt file like this:

+----------------------+                          
|                      |                          
|                      |                          
|                      |                          
|        test          |                          
|                      |                          
|                      |                          
|                      |                          
+------------------------------------------------+
|                      |                         |
|                      |                         |
|                      |                         |
|       Science        |       Bibliothek        |
|                      |                         |
|                      |                         |
|                      |                         |
+----------------------+-------------------------+

when I want to print it using this:

def display_map():
    s = open("map.txt").read()
    return s


print display_map()

it just prints me:

 +----------------------+-------------------------+      

When I try the same method with another text file like:

line 1
line 2
line 3

it works perfectly.

What I do wrong?


Solution

  • I guess this file uses the CR (Carriage Return) character (Ascii 13, or '\r') for newlines; on Windows and Linux this would just move the cursor back to column 1, but not move the cursor down to the beginning of a new line.

    (Of course such line terminators would not survive copy-paste to Stack Overflow, which is why this cannot be replicated).

    You can debug strange characters in a string with repr:

    print(repr(read_map())
    

    It will print out the string with all special characters escaped.


    If you see \r in the repred string, you could try this instead:

    def read_map():
        with open('map.txt') as f:  # with ensures the file is closed properly
            return f.read().replace('\r', '\n') # replace \r with \n
    

    Alternatively supply the U flag to open for universal newlines, which would convert '\r', '\r\n' and '\n' all to the \n upon reading despite the underlying operating system's conventions:

    def read_map():
        with open('map.txt', 'rU') as f:
            return f.read()