酒店预订程序:匹配TXT文件行并删除指定预订的技术难题
解决酒店预订删除匹配问题
咱们先拆解你遇到的核心问题:现有删除代码的逻辑搞反了!你当前是把要删除的匹配行重新写回文件,这反而会保留这些内容;正确的思路应该是把不匹配的行写回文件,让匹配的行被过滤掉。另外还有几个细节可以优化,让删除逻辑更精准、更稳妥,下面一步步来调整:
1. 修正删除逻辑的核心错误
你的现有删除代码:
line_to_match = ';'.join([controller.roomName.get(),controller.roomEmail.get(),controller.roomPhone.get()]) print(line_to_match) with open("Bookings.txt", "r+") as f: line = f.readlines() f.seek(0) for i in line: if i.startswith(line_to_match): f.write(i) f.truncate()
这里的if i.startswith(line_to_match)是把匹配的行写回去,完全和你的需求相反。咱们改成用两次独立的文件操作(读和写),只保留不匹配的行,这样更安全不易出错:
line_to_match = ';'.join([controller.roomName.get(), controller.roomEmail.get(), controller.roomPhone.get()]) print(line_to_match) # 先读取所有行 with open("Bookings.txt", "r") as f: lines = f.readlines() # 重新写入文件,过滤掉匹配的行 with open("Bookings.txt", "w") as f: for line in lines: # 先去掉行尾的换行符再判断,避免换行符干扰匹配 if not line.strip().startswith(line_to_match): f.write(line)
2. 提升匹配精准度(避免误删)
用startswith可能会出现意外匹配的情况——比如有个用户信息是jeff;jeff@gmail.com;123123123;...,另一个是jeffrey;jeff@gmail.com;123123123;...,前者的匹配串会误判后者为匹配项。
建议直接沿用你回显时的分割匹配逻辑,这样和之前的校验规则完全一致,不会误删:
# 获取目标匹配的三个字段,统一处理大小写(和回显逻辑对齐) target_name = controller.roomName.get().upper() target_email = controller.roomEmail.get().upper() target_phone = controller.roomPhone.get() with open("Bookings.txt", "r") as f: lines = f.readlines() with open("Bookings.txt", "w") as f: for line in lines: # 跳过空行,避免写入无效内容 if not line.strip(): continue # 和回显时一样分割数据,只取需要匹配的前三个字段 check_name, check_email, check_phone, _, _, _ = line.strip().split(";") # 只有当行不匹配目标时,才写入文件 if not (check_name.upper() == target_name and check_email.upper() == target_email and check_phone == target_phone): f.write(line)
3. 可选:精准删除单条重复记录
如果你的系统允许同一个用户有多个预订记录,上面的代码会删除所有匹配的行。如果你只想删除当前回显的那一条,可以在回显时保存完整的匹配行:
def edit_details(self,controller): f = open("Bookings.txt") lines = f.readlines() f.close() matched_full_line = None # 新增变量保存完整匹配行 x = -1 for i in lines: x += 1 data = lines[x] first_name1 = str(controller.editName.get()) phonenumber1 = str(controller.editPhone.get()) email1 = str(controller.editEmail.get()) checkfirst_name, checkemail, checkphone_num, checkclock_in_date, checkclock_out_date, checkroom = map(str, data.split(";")) if checkfirst_name.upper() == first_name1.upper() and checkemail.upper() == email1.upper() and checkphone_num == phonenumber1: controller.roomName.set(checkfirst_name) controller.roomEmail.set(checkemail) controller.roomPhone.set(checkphone_num) controller.roomCheckin.set(checkclock_in_date) controller.roomCheckout.set(checkclock_out_date) controller.roomSelect.set(checkroom) matched_full_line = data # 保存完整的匹配行内容 print(controller.roomName.get()) print(controller.roomSelect.get()) controller.show_frame("cancelBooking") # 把匹配行存到controller的变量里,方便删除时调用 controller.matched_booking_line = matched_full_line break elif x > len(lines) - int(2): messagebox.showerror("Error", "Please Enter Valid Details") break
然后删除时直接匹配整行:
with open("Bookings.txt", "r") as f: lines = f.readlines() with open("Bookings.txt", "w") as f: for line in lines: if line != controller.matched_booking_line: f.write(line)
内容的提问来源于stack exchange,提问作者Jefferyfromkmart
相关产品推荐
相关产品推荐

