Xtreme
Xtreme

Reputation: 133

"\n" in strings not working

I have this little piece of code for my sort of Operating System:

print("Type your document below.")
print("Press enter to save.")
print("Type \\n for a new line.")
file=input()
print("Enter a file name...")
filename=input()
outFile = open(filename, "w+")
outFile.write(file)
outFile.close()

but when I run this code (which is in a def), say I enter something like this:

foo \n bar

because enters dont work when recieving input from the users, so you have to use \n.

the file turns out as:

foo \n bar

instead of:

foo
bar

Upvotes: 12

Views: 79671

Answers (3)

Veedrac
Veedrac

Reputation: 60127

Note that if you want to support Python-style strings (with not only \n but also \t, \r, \u1234, etc.), you should use codecs.decode with the unicode_escape handler:

contents = input()
contents = codecs.decode(contents, "unicode_escape")

Note that this will change

foo\nbar\\nbash\u1234

to

foo
bar\nbashሴ

You will also want to handle errors. You can do this either by catching UnicodeDecodeError or by using an error replacement policy:

contents = input()
contents = codecs.decode(contents, "unicode_escape", errors="replace")

Sadly this seems to mess with unicode characters:

codecs.decode("α", "unicode_escape")
#>>> 'α'

The simplest fix I know of is to first escape with raw_unicode_escape:

contents = input()
contents = contents.encode("raw_unicode_escape")
contents = contents.decode("unicode_escape")

This is probably far more complicated than you need, so I suggest not actually doing this.

Upvotes: 7

Martijn Pieters
Martijn Pieters

Reputation: 1121306

\n is an escape sequence that only works in string literals. input() does not take a string literal, it takes the text the user inputs and doesn't do any processing on it so anyone entering \ followed by n produces a string of two characters, a backslash and the letter n, not a newline.

You'll have to do your own processing of such escapes yourself:

file = file.replace(r'\n', '\n')

Here I used a raw string literal, which also doesn't support escapes sequences, to define the literal backslash \ followed by a n.

Alternatively, repeatedly ask users for a new filename, until they are done:

lines = []
print('Type in your document, followed by a blank line:')
while True:
    line = input("> ")
    if not line:
        break
    lines.append(line)
file = '\n'.join(lines)

Demo:

>>> lines = []
>>> print('Type in your document, followed by a blank line:')
Type in your document, followed by a blank line:
>>> while True:
...     line = input("> ")
...     if not line:
...         break
...     lines.append(line)
...
> foo
> bar
>
>>> lines
['foo', 'bar']
>>> '\n'.join(lines)
'foo\nbar'

Upvotes: 21

Wayne Werner
Wayne Werner

Reputation: 51787

As Martijn explained you'll need to process the replacements yourself. The easiest way to do that is literally with the .replace method:

>>> print(input('Enter \\n for newline: ').replace('\\n', '\n'))
Enter \n for newline: This is my \nnewline
This is my 
newline

This will work fine for the \n escape sequence, but if you want others (e.g. \t) then you'll need to implement that yourself.

Upvotes: 12

Related Questions