从外部文本文件登录程序

时间:2017-11-17 06:30:13

标签: python python-3.x

我遇到了代码问题,我必须让用户输入有关自己的详细信息,然后保存到文本文件中。当用户尝试登录时,它将检查文本文件的详细信息。这是我的代码如下。它首先工作,用户被授予访问权限,但每当我重新启动计算机或Python本身时,它只授予最后一次用户访问权限。一些帮助将不胜感激,谢谢:

这就是文本文件中的样子:

Adam16,adam123,Adam,Sunderland,16
Johnny18,johnny150,Johnny,Vane,18

这是源代码:

import csv

import sys

def register():

    firstname = input("First name: ")
    surname = input("Surname: ")
    age = int(input("Age: "))
    password = input("Password: ")

    username = firstname[:3] + str(age)

    with open("account.txt","a",newline="") as myfile:
        writer = csv.writer(myfile)
        writer.writerow([username,password,firstname,surname,age])
        myfile.close()

    menu()



def login():

    user0 = input("Username: ")
    pass0 = input("Password: ")


    file = open("account.txt","r")

    for line in file:
        details = line.split(",")



    if user0 == details[0] and pass0 == details[1]:
        print("Correct!")
    else:
        print("Fail")


    menu()

def menu():

    selection = int(input("1 or 2: "))

    if selection == 1:
        register()
    else:
        login()


menu()

2 个答案:

答案 0 :(得分:0)

您的主要问题是身份识别 - 您的if user0 == details[0] and pass0 == details[1]:for line in file:处于同一缩进状态 - 意味着在 for循环后执行 < / em>它和每个细节。您目前只检查从文件中解析的最后一个detail

您可以通过正确缩进来解决此问题。

这将导致多个输出 - 如果您的用户在第100行,它将打印99失败并且1正确 - 这就是为什么我将打印放在for循环之外。一旦找到正确的用户,您就可以使用break中止循环。

将登录信息更改为:

def login():

    user0 = input("Username: ")
    pass0 = input("Password: ")

    file = open("account.txt","r")
    foundOne = False

    for line in file:
        details = line.split(",")
        # execute Check on each line, not only on last line    
        if user0 == details[0] and pass0 == details[1]:
            foundOne = True
            break # this will instantly leave the for loop of line checkings

    if foundOne == True:
        print("Correct!")
    else:
        print("Fail")

    menu()

我缩进了if ...,因此每行只完成一次而不是一次。我还设置了一个状态,以避免为每个选中的行打印Fail

确保使用正确的用户名 - 它是名字和年龄的组合

答案 1 :(得分:0)

首先让我说,如果我可以避免它,我不想完全重写,我更愿意用尽可能多的原始代码来解决问题。

你的代码没有做到你期望的原因是这一点:

for line in file:
    details = line.split(",")

每次循环读取文件中的下一行时,只会为您提供以details输入的最后一行。然后你从那个for循环出来并检查details,所以它只知道最后一行。

您可以通过多种方式解决此问题,我建议最简单的方法是使用字典而不是列表,以便您可以使用用户文件的内容填充它。您还可以使用csv.reader将您创建的csv文件直接读入列表,而无需先将其拆分:

import csv
def login():

    user_dict = {}
    with open("account.txt", "r") as csvfile:
        authfile = csv.reader(csvfile)
        for line in authfile:
            user_dict[line[0]] = line[1:]

    user0 = input("Username: ")
    if user_dict.get(user0):
        pass0 = input("Password: ")
        if user_dict.get(user0)[1] == pass0:
            print("Correct!")
            menu()
        else:
            print("Bad Password")
    else:
        print("Bad Username")

第一部分创建用户词典并使用您保存到文件的详细信息填充它。第一个条目(用户名)是密钥,其余细节存储在该密钥下的列表中。

从那里,我们获取用户名,然后在字典上执行get请求以确保用户存在(dict.get()如果失败则返回None并且不会引发异常)。如果用户存在,我们会要求输入密码并进行检查。如果密码匹配,则打印出肯定答案并加载菜单功能。如果没有,则通知用户他们提供了错误的密码。

我希望一切都有道理。如果您有任何问题,请告诉我。

编辑:我可能误读了这个。无论如何,看起来所有东西都会回到菜单功能。我确实相信我有点矫枉过正。