C语言变量值存文件及登录验证实现方法问询(附代码)
嘿,作为高二自学编程的你能写出这样的代码已经超棒了!我来帮你一步步解决登录系统的核心问题,顺便给你梳理指针和文件操作的学习思路,让你的期末项目顺利完成~
解决你的日记程序登录系统问题
一、先修正现有代码的几个小问题
你的代码里有几个细节会导致运行异常,先帮你调整:
gets()函数不安全且已被废弃:它会无视缓冲区大小导致溢出,建议换成fgets(),记得处理它读取到的换行符。scanf后的换行符残留:比如输入选项后按回车,这个换行符会留在输入缓冲区里,导致后续输入直接读到空内容,需要用getchar()清理。- 值传递的坑:原来的
signUp函数里age是值传递,函数内修改的只是副本,主函数里的age不会被更新,换成指针参数才能传递真实输入的年龄。 - 文件写入错误:
fputs("%s", username)不会解析格式字符串,应该用fprintf来格式化写入内容。
修正后的signUp函数示例:
#include <stdio.h> #include <stdlib.h> #include <string.h> // 要包含这个头文件处理字符串 #define SIZE 1000 void signUp (char username[SIZE], char password[SIZE], char name[SIZE], int *age) { printf("\nSign Up Procedure: \n"); // 清理之前scanf留下的换行符 while (getchar() != '\n'); printf("Please enter your username: "); fgets(username, SIZE, stdin); // 去掉fgets读取到的换行符 username[strcspn(username, "\n")] = '\0'; printf("Please enter a password: "); fgets(password, SIZE, stdin); password[strcspn(password, "\n")] = '\0'; printf("Enter your full name: "); fgets(name, SIZE, stdin); name[strcspn(name, "\n")] = '\0'; printf("Enter your age: "); scanf("%d", age); // 因为age是指针,不用加& printf("\nUsername: %s, Password: %s, Full Name: %s, Age: %d\n", username, password, name, *age); }
二、实现用户信息写入文件
我们可以把每个用户的信息用逗号分隔的格式存在users.txt里(比如用户名,密码,真实姓名,年龄),这样后续读取解析会很方便。注意用追加模式("a")打开文件,避免清空已有的用户数据:
// 注册完成后调用这个函数保存用户信息 void saveUser(char username[SIZE], char password[SIZE], char name[SIZE], int age) { FILE *pfile = fopen("users.txt", "a"); if (pfile == NULL) { printf("Error opening file! Can't save your info.\n"); exit(1); } // 用fprintf格式化写入,字段用逗号分隔 fprintf(pfile, "%s,%s,%s,%d\n", username, password, name, age); fclose(pfile); printf("Sign up successful! Your info has been saved.\n"); }
然后在主函数的case 2里调用这个函数:
case (2): signUp(username, password, name, &age); // 传age的地址给指针参数 saveUser(username, password, name, age); keepGoing = 1; break;
三、实现登录验证功能
登录时需要从users.txt逐行读取用户信息,拆分字段后和用户输入的账号密码对比:
int logIn(char inputUsername[SIZE], char inputPassword[SIZE]) { FILE *pfile = fopen("users.txt", "r"); if (pfile == NULL) { printf("No users found! Please sign up first.\n"); return 0; // 登录失败返回0 } char line[SIZE * 4]; // 足够容纳一行用户信息 char storedUsername[SIZE], storedPassword[SIZE], storedName[SIZE]; int storedAge; printf("\nLog In Procedure: \n"); printf("Enter your username: "); fgets(inputUsername, SIZE, stdin); inputUsername[strcspn(inputUsername, "\n")] = '\0'; printf("Enter your password: "); fgets(inputPassword, SIZE, stdin); inputPassword[strcspn(inputPassword, "\n")] = '\0'; // 逐行读取文件内容 while (fgets(line, sizeof(line), pfile) != NULL) { // 用sscanf拆分逗号分隔的字段 sscanf(line, "%[^,],%[^,],%[^,],%d", storedUsername, storedPassword, storedName, &storedAge); // 对比用户名和密码,用strcmp判断字符串是否相等 if (strcmp(storedUsername, inputUsername) == 0 && strcmp(storedPassword, inputPassword) == 0) { printf("Login successful! Welcome back, %s!\n", storedName); fclose(pfile); return 1; // 登录成功返回1 } } // 遍历完所有用户都没匹配上 printf("Invalid username or password!\n"); fclose(pfile); return 0; }
主函数调用时记得先清理缓冲区:
case (1): while (getchar() != '\n'); // 清理之前的换行符 if (logIn(username, password)) { // 登录成功后可以添加日记读写功能 printf("Opening your diary...\n"); } keepGoing = 1; break;
四、指针和文件操作的学习建议
指针学习
- 从基础概念入手:先理解指针是存储变量地址的变量,比如
int *p表示p是指向int类型的指针,*p是取指针指向的值,&x是取变量x的地址。 - 先练简单场景:比如用指针修改函数外的变量(像我们修改age那样),用指针遍历数组,理解数组名本质是指向第一个元素的指针(
arr[0]等价于*arr)。 - 逐步进阶:慢慢接触指针数组、指向指针的指针,不用急于求成,先把基础用熟。
文件操作学习
- 先记牢常用打开模式:
"r"(只读)、"w"(清空写入)、"a"(追加写入)、"r+"(读写),每次打开文件都要检查是否成功(if (pfile == NULL))。 - 掌握三类读写方式:
- 格式化读写:
fprintf、fscanf(适合结构化数据) - 整行读写:
fgets、fputs(适合文本行) - 单个字符读写:
fgetc、fputc(适合逐字符处理)
- 格式化读写:
- 重点理解文件指针的移动:每次读写操作后,文件指针会自动移动到下一个位置,也可以用
fseek手动调整。
整合后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 1000 void signUp (char username[SIZE], char password[SIZE], char name[SIZE], int *age) { printf("\nSign Up Procedure: \n"); while (getchar() != '\n'); printf("Please enter your username: "); fgets(username, SIZE, stdin); username[strcspn(username, "\n")] = '\0'; printf("Please enter a password: "); fgets(password, SIZE, stdin); password[strcspn(password, "\n")] = '\0'; printf("Enter your full name: "); fgets(name, SIZE, stdin); name[strcspn(name, "\n")] = '\0'; printf("Enter your age: "); scanf("%d", age); printf("\nUsername: %s, Password: %s, Full Name: %s, Age: %d\n", username, password, name, *age); } void saveUser(char username[SIZE], char password[SIZE], char name[SIZE], int age) { FILE *pfile = fopen("users.txt", "a"); if (pfile == NULL) { printf("Error opening file! Can't save your info.\n"); exit(1); } fprintf(pfile, "%s,%s,%s,%d\n", username, password, name, age); fclose(pfile); printf("Sign up successful! Your info has been saved.\n"); } int logIn(char inputUsername[SIZE], char inputPassword[SIZE]) { FILE *pfile = fopen("users.txt", "r"); if (pfile == NULL) { printf("No users found! Please sign up first.\n"); return 0; } char line[SIZE * 4]; char storedUsername[SIZE], storedPassword[SIZE], storedName[SIZE]; int storedAge; printf("\nLog In Procedure: \n"); printf("Enter your username: "); fgets(inputUsername, SIZE, stdin); inputUsername[strcspn(inputUsername, "\n")] = '\0'; printf("Enter your password: "); fgets(inputPassword, SIZE, stdin); inputPassword[strcspn(inputPassword, "\n")] = '\0'; while (fgets(line, sizeof(line), pfile) != NULL) { sscanf(line, "%[^,],%[^,],%[^,],%d", storedUsername, storedPassword, storedName, &storedAge); if (strcmp(storedUsername, inputUsername) == 0 && strcmp(storedPassword, inputPassword) == 0) { printf("Login successful! Welcome back, %s!\n", storedName); fclose(pfile); return 1; } } printf("Invalid username or password!\n"); fclose(pfile); return 0; } int main() { printf("1. Log In\n"); printf("2. Sign Up\n"); int choice; printf("Choice: "); scanf("%d", &choice); char username[SIZE]; char password[SIZE]; char name[SIZE]; int age; int keepGoing = 0; while (keepGoing == 0) { switch (choice) { case (1): while (getchar() != '\n'); if (logIn(username, password)) { printf("You can now write your diary!\n"); } keepGoing = 1; break; case (2): signUp(username, password, name, &age); saveUser(username, password, name, age); keepGoing = 1; break; default: printf("Please enter a choice from the given options (1 or 2)\n"); printf("Choice: "); scanf("%d", &choice); break; } } return 0; }
内容的提问来源于stack exchange,提问作者Zillua
相关产品推荐
相关产品推荐

