ATM项目:如何将文本文件中账户信息按组存入数组并实现访问
问题解决思路与修正代码
你的代码存在两个核心问题导致无法正常工作,还有几个可优化的点,一步步拆解解决:
1. 核心错误修复
(1)数组元素未初始化
你创建了BankAccount[] tabBankAccounts = new BankAccount[200];,但数组里的每个元素默认都是null,直接赋值tabBankAccounts[i].AccountNumber会触发空引用异常,必须先为每个索引创建BankAccount实例。
(2)循环未递增索引i
你的while循环里没有i++,所有账户数据都会覆盖到tabBankAccounts[0],最终数组里只会保留最后一个账户的信息。
2. 修正后的读取文件代码
// 使用using语句自动释放资源,无需手动调用Close using (StreamReader myfile = new StreamReader("AccountInfo.txt")) { short i = 0; // 同时检查数组是否越界,避免超过200个账户导致崩溃 while (!myfile.EndOfStream && i < tabBankAccounts.Length) { // 先初始化当前索引的BankAccount对象 tabBankAccounts[i] = new BankAccount(); // 读取并去除每行可能的空白字符 tabBankAccounts[i].AccountNumber = myfile.ReadLine()?.Trim(); tabBankAccounts[i].Name = myfile.ReadLine()?.Trim(); // 增加格式校验,避免文件内容错误导致程序崩溃 if (short.TryParse(myfile.ReadLine()?.Trim(), out short nip)) { tabBankAccounts[i].NIP = nip; } else { Console.WriteLine($"第{i+1}个账户的NIP格式错误,已跳过该账户"); // 跳过剩余2行(每组4行,已读2行) myfile.ReadLine(); myfile.ReadLine(); i++; continue; } if (int.TryParse(myfile.ReadLine()?.Trim(), out int balance)) { tabBankAccounts[i].TotalBalance = balance; } else { Console.WriteLine($"第{i+1}个账户的余额格式错误,已跳过该账户"); i++; continue; } i++; // 处理完一个账户,索引递增 } }
3. 根据账号查找账户的实现
要实现用户输入账号后访问对应信息,有两种常用方案:
方案1:遍历数组查找(适合小规模账户)
BankAccount FindAccountByNumber(string accountNumber) { foreach (var account in tabBankAccounts) { // 跳过未初始化的空元素 if (account != null && account.AccountNumber == accountNumber) { return account; } } return null; // 找不到返回null } // 使用示例 string inputAccount = Console.ReadLine(); var targetAccount = FindAccountByNumber(inputAccount); if (targetAccount != null) { Console.WriteLine($"姓名:{targetAccount.Name},余额:{targetAccount.TotalBalance}"); } else { Console.WriteLine("账号不存在"); }
方案2:用Dictionary存储(查找效率更高,推荐)
如果账户数量较多,遍历数组效率低,可以在读取文件时同步构建字典:
Dictionary<string, BankAccount> accountDict = new Dictionary<string, BankAccount>(); // 读取文件时同步填充字典 using (StreamReader myfile = new StreamReader("AccountInfo.txt")) { while (!myfile.EndOfStream) { var account = new BankAccount(); account.AccountNumber = myfile.ReadLine()?.Trim(); account.Name = myfile.ReadLine()?.Trim(); short.TryParse(myfile.ReadLine()?.Trim(), out account.NIP); int.TryParse(myfile.ReadLine()?.Trim(), out account.TotalBalance); // 确保账号不为空再加入字典 if (!string.IsNullOrEmpty(account.AccountNumber)) { accountDict[account.AccountNumber] = account; } } } // 查找示例 string inputAccount = Console.ReadLine(); if (accountDict.TryGetValue(inputAccount, out var targetAccount)) { Console.WriteLine($"姓名:{targetAccount.Name},余额:{targetAccount.TotalBalance}"); } else { Console.WriteLine("账号不存在"); }
额外优化建议
- 不要固定数组大小为200,改用
List<BankAccount>更灵活,避免空间浪费或溢出 - 对读取的每一行做非空检查,避免
null值引发的问题 - 将账户信息的读取逻辑封装成单独方法,代码结构更清晰
内容的提问来源于stack exchange,提问作者Optik
相关产品推荐
相关产品推荐

