程序功能
- 用户登录:预设一个用户名和密码,用户输入正确后才能使用ATM功能。
- 主菜单:登录成功后,显示操作菜单。
- 查询余额:显示当前账户的余额。
- 取款:用户可以输入取款金额,程序会检查余额是否充足,并更新余额。
- 退出:退出ATM程序。
- 循环操作:在用户选择退出前,可以一直进行操作。
C语言代码
#include <stdio.h>
#include <string.h> // 用于字符串比较函数 strcmp
#include <stdlib.h> // 用于清屏函数 system
// --- 全局变量定义 ---
// 为了简化,我们将账户信息定义为全局变量
// 在实际应用中,这些数据应该存储在数据库或文件中
float balance = 10000.0f; // 初始余额
const char *correct_username = "admin";
const char *correct_password = "123456";
// --- 函数声明 ---
void showMenu();
void checkBalance();
void withdrawMoney();
void clearInputBuffer();
// --- 主函数 ---
int main() {
char username[50];
char password[50];
int loginAttempts = 0;
const int maxAttempts = 3;
printf("====================================\n");
printf(" 欢迎使用简易ATM系统\n");
printf("====================================\n");
// 登录验证循环
while (loginAttempts < maxAttempts) {
printf("\n请输入用户名: ");
scanf("%s", username);
printf("请输入密码: ");
scanf("%s", password);
// 检查用户名和密码是否正确
if (strcmp(username, correct_username) == 0 && strcmp(password, correct_password) == 0) {
printf("\n登录成功!正在进入系统...\n");
// 登录成功后,进入主操作循环
int choice;
do {
showMenu();
printf("请输入您的选择 (1-4): ");
scanf("%d", &choice);
// 根据用户选择调用相应功能
switch (choice) {
case 1:
checkBalance();
break;
case 2:
withdrawMoney();
break;
case 3:
printf("\n感谢使用,正在退出...\n");
break;
case 4:
printf("\n感谢使用,正在退出...\n");
break;
default:
printf("\n无效的输入,请输入 1 到 4 之间的数字,\n");
break;
}
} while (choice != 3 && choice != 4); // 当用户选择3或4时退出循环
break; // 登录成功并完成操作后,退出外层循环
} else {
loginAttempts++;
printf("\n用户名或密码错误!\n");
if (loginAttempts < maxAttempts) {
printf("您还有 %d 次尝试机会,\n", maxAttempts - loginAttempts);
} else {
printf("错误次数过多,ATM卡将被锁定,请联系银行,\n");
}
}
}
printf("\n====================================\n");
printf(" 感谢使用,再见!\n");
printf("====================================\n");
return 0;
}
// --- 函数定义 ---
/**
* @brief 显示ATM主菜单
*/
void showMenu() {
printf("\n--- ATM 主菜单 ---\n");
printf("1. 查询余额\n");
printf("2. 取款\n");
printf("3. 退出\n");
printf("4. 退出 (备用选项)\n");
printf("------------------\n");
}
/**
* @brief 查询并显示当前余额
*/
void checkBalance() {
printf("\n--- 账户余额查询 ---\n");
printf("您的当前余额为: ¥%.2f\n", balance);
printf("--------------------\n");
}
/**
* @brief 处理取款逻辑
*/
void withdrawMoney() {
float amount;
printf("\n--- 取款 ---\n");
printf("请输入您要取款的金额: ¥");
scanf("%f", &amount);
// 检查输入金额是否有效
if (amount <= 0) {
printf("取款金额必须大于零,\n");
}
// 检查余额是否充足
else if (amount > balance) {
printf("取款失败!余额不足,\n");
printf("您的当前余额为: ¥%.2f\n", balance);
}
// 成功取款
else {
balance -= amount;
printf("取款成功!\n");
printf("您已取款: ¥%.2f\n", amount);
printf("您的当前余额为: ¥%.2f\n", balance);
}
printf("-------------\n");
}
/**
* @brief 清空输入缓冲区,防止用户输入非数字导致程序错误
* 这是一个很好的编程习惯,可以增强程序的健壮性。
*/
void clearInputBuffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF);
}
如何编译和运行
- 保存代码:将上面的代码复制并粘贴到一个文本编辑器中,保存为
atm.c。 - 打开终端/命令提示符:
- 在 Windows 上,可以打开 "命令提示符" 或 "PowerShell"。
- 在 macOS 或 Linux 上,打开 "终端"。
- 编译代码:使用 GCC 编译器进行编译,输入以下命令:
gcc atm.c -o atm
gcc是编译器的名字。atm.c是你的源文件名。-o atm指定输出的可执行文件名为atm。
- 运行程序:编译成功后,运行生成的可执行文件:
- 在 Windows 上:
atm.exe - 在 macOS 或 Linux 上:
./atm
- 在 Windows 上:
代码讲解
-
全局变量:
(图片来源网络,侵删)balance:存储账户余额,初始化为10000.0。correct_username和correct_password:存储预设的用户名和密码,使用const关键字表示它们是常量,不应被修改。
-
main函数:- 登录逻辑:使用
while循环和if语句来验证用户输入的用户名和密码。strcmp函数用于比较两个字符串是否完全相同。 - 错误处理:限制了登录尝试次数(3次),超过后程序会提示并退出。
- 主循环:使用
do-while循环来持续显示菜单并等待用户输入,直到用户选择退出(3或4)。 switch语句:根据用户输入的数字(choice),调用不同的功能函数。
- 登录逻辑:使用
-
功能函数:
showMenu():简单的printf函数,用于打印菜单界面。checkBalance():直接打印balance变量的值,格式化为两位小数(%.2f)。withdrawMoney():- 获取用户输入的取款金额。
- 使用
if-else if-else结构进行多重判断:检查金额是否合法(>0)、检查余额是否充足。 - 根据判断结果给出相应的提示,并更新余额。
-
#include指令:<stdio.h>:标准输入输出库,用于printf和scanf。<string.h>:字符串处理库,用于strcmp函数。
程序的局限性与改进方向
这个程序非常基础,仅用于学习和演示,一个真实的ATM系统需要考虑更多:

(图片来源网络,侵删)
- 数据持久化:当前程序关闭后,余额会重置,应该使用文件(如
data.txt)或数据库来存储用户信息和账户余额。 - 安全性:
- 密码不应以明文形式存储或显示。
- 输入密码时,应该显示 或其他掩码字符。
- 应该有更复杂的登录验证机制。
- 错误处理:
- 对
scanf的返回值进行检查,防止用户输入非数字导致程序崩溃。 - 我添加了一个
clearInputBuffer函数的注释,这是一个很好的改进点。
- 对
- 功能扩展:
- 存款:增加一个存款功能。
- 转账:实现用户之间的转账功能。
- 多用户管理:使用结构体或链表来管理多个用户账户。
- 交易记录:记录每一次存款、取款操作。
- 图形用户界面:使用如
ncurses(Linux/macOS) 或 Windows API 来创建更友好的界面。
你可以尝试从这些方向入手,逐步完善这个简易程序,让它变得更强大、更接近真实的应用。
