0

I have a txt file with content as below: name password number location

the four items are separated into each line

I would like to change the content in the specific line, eg: change the third line("number") to "phone number"

Problem I faced is not replacing the "number", "number" still there, and the "phone number" is appended at the last line

Output:
name
password
number
location
phone number

How should I fix the code, so it can replace the content in certain line?

Below is my code

userID = 1

print("Modify: ")
print("1. Username")
print("2. Password")
print("3. Contact number")
print("4. Location")
print()
print("Enter 'main' to back to main screen")
select = int(input())
change = input("Change to: ")

if select != 'main:':
    if int(select) <= 4:
        #save to individual file
        fhand = open("user_"+str(userID)+".txt",'r+') 
        
        lineNo = 0 #line number
        for line in fhand(): 
            lineNo = lineNo + 1
            if lineNo == select:
                fhand.write(line.replace(line, change)) #replace the content
                print()
                print("Changed to:", change)
                print("Change successful")
                print("\n Bring you back to <customer main menu>")
 
        fhand.close()

I tried counting the line number, then when the line number reach the selection of the user, it starts to replace the line, and it doesn't work

Thanks for the helps

  • 2
    This is not the code you're running. The code you posted cannot run because of `for line in fhand(): ` - file is not callable, it raises an error. Please provide the code you're actually running – h4z3 Jun 17 '21 at 13:09
  • https://stackoverflow.com/questions/5453267/is-it-possible-to-modify-lines-in-a-file-in-place – Peter Wood Jun 17 '21 at 13:15
  • Sidenote, `int(input())` before you check `if select != 'main'` is going to raise `ValueError` when you input `'main'`. – adamkwm Jun 17 '21 at 13:20
  • Apologise that I removed .readlines and didn't notice `for line in fhand.readlines():` should be correct and running without error, just the output is incorrect. ya haven't test for giving input 'main', thanks for reminding – hijunxian0805 Jun 17 '21 at 13:27

5 Answers5

0

You can't edit or replace a single line in a file. Try to open a second file (e.g.newtext = open("newtext.txt", "a+") and do something like this:

for line in fhand.readlines():
    if line != select:
        newtext.write(line)
    else:
        line = line.replace(line, change)
        newtext.write(line)

also, try using with open as statements, for example

with open("newtext.txt", "a+") as newtext:
    for line in fhand.readlines():
        if line != select:
            newtext.write(line)
        else:
            line = line.replace(line, change)
            newtext.write(line)
Dakopen
  • 62
  • 11
  • That's false. Read+write mode serves exactly this purpose. It's just that OP posted wrong code (with error), so we can't even analyze what's wrong – h4z3 Jun 17 '21 at 13:11
  • You could do the reading and writing all in one like this https://pythonexamples.org/python-replace-string-in-file/ article suggests, but that's basically my solution without a second file. I thought, especially for beginners, it is easier to do it in separate files. – Dakopen Jun 17 '21 at 13:14
  • https://stackoverflow.com/questions/5453267/is-it-possible-to-modify-lines-in-a-file-in-place – Peter Wood Jun 17 '21 at 13:15
0

Quickest fix would be to read the whole file, close it, and rewrite with the correct data. This way you ensure that the new file has the correct contents.

I highly advise you to switch to using JSON files though. You won't have the same issue as you can load a JSON file as a dict, change the correct value, and rewrite the changed dict/JSON. Structured datafiles FTW...

Adjusting the current code, see below.

userID = 1

print("Modify: ")
print("1. Username")
print("2. Password")
print("3. Contact number")
print("4. Location")
print()
print("Enter 'main' to back to main screen")
select = int(input()) - 1 # offset difference between selection options and 0-based list
change = input("Change to: ")

if select != 'main:':
    if select < 4 and select >= 0:  # adjusted due to adjusting the select above
        filename = f'user_{str(userID)}.txt'
        # load file
        with open(filename) as infile:
            filecontents = infile.readlines()
        # make the change
        filecontents[select] = f'{change}\n'
        # save the result
        with open(filename, 'w') as outfile:
            outfile.writelines(filecontents)
        print()
        print("Changed to:", change)
        print("Change successful")
        print("\n Bring you back to <customer main menu>")

Edo Akse
  • 4,051
  • 2
  • 10
  • 21
0

the filemode r+ is reading and appending, so if you want to change the existing contents of the file then you have to open the file in write mode.

userID = 1

print("Modify: ")
print("1. Username")
print("2. Password")
print("3. Contact number")
print("4. Location")
print()
print("Enter 'main' to back to main screen")
select = int(input())
change = input("Change to: ")

if select != 'main:':
    if int(select) <= 4:
        #save to individual file
        with open("user_"+str(userID)+".txt",'r') as f:
            lines = f.readlines()
        # fhand = open("user_"+str(userID)+".txt",'r+') 
        
        lineNo = 0 #line number
        for line in lines: 
            lineNo = lineNo + 1
            if lineNo == select -1:
                lines[lineNo] = line.replace(line, f'{change}\n')
                with open("user_"+str(userID)+".txt",'w') as f:
                    f.write("".join(lines)) #replace the content
                print()
                print("Changed to:", change)
                print("Change successful")
                print("\n Bring you back to <customer main menu>")
                break
 
        # fhand.close()

I have taken the liberty to change some variable names; do change to your usecase accordingly.

0

Instead of that, what you can do is go with this code for editing the text file

with open(path_to_text_file,'r') as txt:
    text=txt.readlines()
    text[3]='phone number\n'

    with open(path_to_text_file,'w') as txt:
        txt.writelines(text)
Bibekjit Singh
  • 142
  • 1
  • 1
  • 9
0

slight modifications:

userID = 1

print("Modify: ")
print("1. Username")
print("2. Password")
print("3. Contact number")
print("4. Location")
print()
print("Enter 'main' to back to main screen")
select = int(input())-1
change = input("Change to: ")

if select != 'main:':
    if int(select) <= 4:
        # save to individual file
        with open("user_" + str(userID) + ".txt", 'r+') as file:
            data = file.readlines()
        for index, line in enumerate(data):
            if index == select:
                data[index] = line.replace(line, f"{change}\n")
                break
        with open("user_" + str(userID) + ".txt", 'r+') as file:
            file.writelines(data)
        print("Changed to:", change)
        print("Change successful")
        print("\n Bring you back to <customer main menu>")
David Meu
  • 1,527
  • 9
  • 14