Search a specific line in a . txt file and change the content

Asked

Viewed 405 times

-1

I have a file containing in each line a CPF number, name and login, separated by comma. Ex:

  12345678910, gabriel barbosa, [email protected]
  09876543211, carlos silva, [email protected]

The user should be able to change the name, locating it through the CPF, which will be informed by the own. If the CPF does not exist in the file, the program must inform that it does not exist.

I used this code:

inserir a descrição da imagem aqui

I have two txt files:

inserir a descrição da imagem aqui

Arq.txt looks like this:

inserir a descrição da imagem aqui

The new.txt file is empty.

Running the code:

inserir a descrição da imagem aqui

the contents of Arq.txt go to the new_arq.txt, with the changes in the name:

inserir a descrição da imagem aqui

So far so good, however, when I change another line, the content of novo_arq.txt is overwritten and the previous change is lost:

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

What can I do to fix?

  • Gabriel, could you clarify better what precisely you tried? If possible, edit your post by presenting at least one of the attempts

  • https://repl.it/repls/ThankfulPrimarySymbol That?

  • Gabriel, please enter the code and other files as text. Putting as image is not ideal, understand the reasons reading the FAQ. Anyway, the problem is that you always read from Arq.txt and update the new_arq.txt. If you want the original file to have the change, at the end vc should rename the new_arq.txt to Arq.txt

4 answers

1


What you have is a file CSV (Comma-separated values, literally "comma separated values"), so a good alternative is to use the module csv to read it. An initial outline:

import csv

with open('arquivo.txt') as arquivo:
    reader = csv.reader(arquivo)
    for registro in reader:
        cpf = registro[0].strip()

First I open the file inside a block with, for this assures me that the file is properly closed at the end of the execution.

Then I use csv.reader to iterate through the records of the file. In this case, every iteration of the for, the variable registro will be a list of strings, each element of the list being one of the records (i.e., the first element is CPF, the second is the name, etc).

Then I take the number and use strip() to remove the spaces from the beginning, as it is not clear in the question whether they are part of the file or if it was a typo. Anyway, now just compare this number with what was typed. It would look something like this:

import csv

cpf_informado = input('informe o CPF: ')
with open('arquivo.txt') as arquivo:
    reader = csv.reader(arquivo)
    for registro in reader:
        cpf = registro[0].strip()
        if cpf == cpf_informado:
            print('CPF encontrado')
            break
    else:
        print('CPF não encontrado')

If the number is found, I can leave the loop with break. If not found, he falls else. And notice that this else is from for, not of if: in Python this is possible, and he falls in else if the loop is not interrupted by break (in case, if no CPF is found).


You also said you want to update the name when the number is found. In this case, an alternative is to create another file containing the updated records:

import csv

cpf_informado = input('informe o CPF: ')
with open('arquivo.txt') as arquivo, open('novoarquivo.txt', 'w', newline='') as novo_arquivo:
    reader = csv.reader(arquivo)
    writer = csv.writer(novo_arquivo)
    encontrou = False
    for registro in reader:
        cpf = registro[0].strip()
        if cpf == cpf_informado:
            encontrou = True
            registro[1] = input('Digite o novo nome: ')
        writer.writerow(registro)

    if not encontrou:
        print('CPF não foi encontrado')

Now you can’t use it break because I need to continue the loop writing all the records in the new file.

This algorithm was not so good, because in case the CPF is not found, I created the new file for nothing. Then you could save the records in a list, and only create the new file if the CPF is found:

import csv

cpf_informado = input('informe o CPF: ')
with open('arquivo.txt') as arquivo:
    reader = csv.reader(arquivo)
    encontrou = False
    registros = [registro for registro in reader]
    for registro in registros:
        cpf = registro[0].strip()
        if cpf == cpf_informado:
            encontrou = True
            registro[1] = input('Digite o novo nome: ')

    if not encontrou:
        print('CPF não foi encontrado')
    else:
        with open('novoarquivo.txt', 'w', newline='') as novo_arquivo:
            writer = csv.writer(novo_arquivo)
            for registro in registros:
                writer.writerow(registro)

The line registros = [registro for registro in reader] creates the list registros, containing the records of the file. It uses the syntax of comprehensilist on, much more succinct and pythonic.

Note that now I only open the new file if the CPF is found. Otherwise, I just print the message.

Just remembering that this solution loads the entire file in memory, so if the file is too large, it is not suitable, requiring there other solutions. But I think that’s beyond the scope of the question.


As for your other problem, of "losing" the changes made, it happens because you always read from the original file and update in the new file (ie you read from the original data, and the new file always has only the last update).

In this case, you could overwrite the file itself at the end:

import csv

cpf_informado = input('informe o CPF: ')
with open('arquivo.txt') as arquivo:
    reader = csv.reader(arquivo)
    encontrou = False
    registros = [registro for registro in reader]
    for registro in registros:
        cpf = registro[0].strip()
        if cpf == cpf_informado:
            encontrou = True
            registro[1] = input('Digite o novo nome: ')

if not encontrou:
    print('CPF não foi encontrado')
else:
    with open('arquivo.txt', 'w', newline='') as novo_arquivo:
        writer = csv.writer(novo_arquivo)
        for registro in registros:
            writer.writerow(registro)

I mean, first I read the file and I read the list with the records.

Then off the block with, I check if the CPF was found, and overwrite the file itself with the new records. This way you don’t "lose" the changes made next time you change another record.

  • The only problem is that, for example, I can change a line, but if I change another line, the line I changed previously goes back to the initial state...

  • @Gabrielbarbosa Updated the answer

0

Gabriel, your question is a little confused or you don’t have enough information. Anyway I interpreted and made a simple code that searches if the CPF is contained in the file. For tests just put the following code in the same directory as the test.txt file (or the name you want):

print("Hello! Type the CPF number:")
search = input()

print("Searching...")
file = open("teste.txt","r") 
for line in file.readlines():
    if (search in line):
        print("Great! We have found your search!")
        break
  • The program should ask for the CPF and look for it in the file, so that’s okay, so it should go to the line where the CPF was found, and ask for a new name. For example, if the line is like this: 12345678910, Openel Barbosa, [email protected], the name in this case is 'Openel Barbosa', then it would ask for a new name for the user. Let’s assume he typed "Abriel b", so it would be: 12345678910, Abriel b, [email protected]

  • Because you didn’t use line.split(", ") to separate the data ?

-1

Bro when you use the with open('archival', 'w'....) This 'w' overwrites the TXT file, you need to use 'a' as it concatenates the file... Thus: with open('seuseufile.txt', 'a') as file: file.write('what you type here it concatenates into the file and does not erase what had before! ') É nois...

-1

Hello Gabriel Barbosa and fellow programmers.

Solution:

print("Hello! Type the CPF number:")
search = input()

print("Searching...")
file = open("teste.txt", "r")

def result(search, file):
    resultado = "Not Found"
    index = 0
    lines = file.readlines()
    file_text = "".join(lines)
    for line in lines:
        dados = line.split(", ")
        cpf = dados[0].replace(" ", "")
        if (cpf == search):
            resultado = "Great! We have found your search!"
            print("Your new username:")
            value = input()
            dados[1] = value
            lines[index] = ", ".join(dados)
            file_text = "".join(lines)
            break
        index += 1
    return {
        "resultado": resultado,
        "file_text": file_text
    }


print(result(search, file)["file_text"])

Browser other questions tagged

You are not signed in. Login or sign up in order to post.