0

I'm creating a program to allow users to remove users which works, however, when it removes a user at the end of the file a new line character is not removed which breaks the program. The following is the a part of the function to remove the user.

with open("users.txt", "r") as input:
    with open("temp.txt", "w") as output:  # Iterate all lines from file
        for line in input:
            if not line.strip("\n").startswith(enteredUsername):  
            # If line doesn't start with the username entered, then write it in temp file.
                output.write(line)
os.replace('temp.txt', 'users.txt')  # Replace file with original name

This creates a temporary file where anything which doesn't start with a given string is written to the file. the name is then swapped back to "users.txt" I've looked on other threads on stackoverflow as well as other websites and nothing has worked, is there anything I should change about this solution?

EDIT --------------------

I managed to fix this with the following code (and thanks to everyone for your suggestions!):

count = 1  # Keeps count of the number of lines
removed = False  # Initially nothing has been removed
with open(r"users.txt", 'r') as fp:
    x = len(fp.readlines())  # Finds the number of lines in the file

    if login(enteredUsername, enteredPassword) == True:  # Checks if the username and password combinination is correct
        with open("users.txt", "r") as my_input:
            with open("temp.txt", "w") as output:  # Iterate all lines from file

                for line in my_input:
                    
                    if not line.strip("\n").startswith(enteredUsername):  # If line doesn't start with the username entered, then write it in temp file.
                        if count == x - 1 and removed == False:  # If something has not been removed, get rid of newline character
                            output.write(line[:-1])

                        else:
                            output.write(line)
                    else:
                        removed = True  # This only becomes true if the previous statement is false, if so, something has been 'removed'
                    
                    count +=1  # Increments the count for every line

        os.replace('temp.txt', 'users.txt')  # Replace file with original name
hello
  • 1
  • 1
  • Note that `input` is a built-in so you might want to rename it. Why not just do `output.write(line.strip('\n'))`? – jtlz2 Aug 17 '22 at 14:32
  • `line.strip()` returns a _new_ copy of the line; it does not modify the existing line. So when you then call `output.write(line)`, it's using the original non-stripped line. – John Gordon Aug 17 '22 at 14:48
  • Stripping the line then adding it to the file results in all new lines being removed. I only want the final line being removed (which only happens when I wish to remove a user at the end of a file) – hello Aug 17 '22 at 20:22

2 Answers2

0
with open("users.txt", "r") as input:
    with open("temp.txt", "w") as output:  # Iterate all lines from file
        for line in input:
            if not line.strip("\n").startswith(enteredUsername):  
            # If line doesn't start with the username entered, then write it in temp file.
                # output.write(line)  # <-- you are writing the line that still have the new line character
                output.write(line.strip("\n"))  # try this?
os.replace('temp.txt', 'users.txt')  # Replace file with original name

Also as general tip I would recommend not using the term "input" as a variable name since it is reserved in python. Just letting you know as it can potentially cause some whacky errors that can be a pain to debug (speaking from personal experience here!)

================================================================

EDIT: I realize that doing this will likely not have any new line characters after you write the line, which will have all usernames on the same line. You will need to write a new line character after every name you write down except for the last one, which give you the trailing new line character that is causing you the problem.

with open("users.txt", "r") as my_input:
    with open("temp.txt", "w") as output:  # Iterate all lines from file
        for line in my_input:
            if not line.strip("\n").startswith(enteredUsername):  
            # If line doesn't start with the username entered, then write it in temp file.
                output.write(line)
os.replace('temp.txt', 'users.txt')  # Replace file with original name

# https://stackoverflow.com/questions/18857352/remove-very-last-character-in-file
# remove last new line character from the file
with open("users.txt", 'rb+') as filehandle:
    filehandle.seek(-1, os.SEEK_END)
    filehandle.truncate()

This is admittedly a hackey way to go about it-- but it should work! This last section removes the last character of the file, which is a new line character.

Mitchnoff
  • 495
  • 2
  • 7
0

You don't need to use a temporary file for this.

def remove_user(filename, enteredUsername):
    last = None
    with open(filename, 'r+') as users:
        lines = users.readlines()
        users.seek(0)
        for line in lines:
            if not line.startswith(enteredUsername):
                users.write(line)
                last = line
        # ensure that the last line is newline terminated
        if last and last[-1] != '\n':
            users.write('\n')
        users.truncate()
DarkKnight
  • 19,739
  • 3
  • 6
  • 22
  • Thank you for commenting. Unfortunately this doesn't work and the newline still persists when a user has been removed at the end of a file. – hello Aug 17 '22 at 20:17
  • @hello Are you saying that the last line in the file should **not** be newline terminated? – DarkKnight Aug 18 '22 at 06:53
  • The last line in the file should have a a username and a password and should not be a newline. – hello Aug 18 '22 at 15:55