You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言变量值存文件及登录验证实现方法问询(附代码)

嘿,作为高二自学编程的你能写出这样的代码已经超棒了!我来帮你一步步解决登录系统的核心问题,顺便给你梳理指针和文件操作的学习思路,让你的期末项目顺利完成~

解决你的日记程序登录系统问题

一、先修正现有代码的几个小问题

你的代码里有几个细节会导致运行异常,先帮你调整:

  1. gets()函数不安全且已被废弃:它会无视缓冲区大小导致溢出,建议换成fgets(),记得处理它读取到的换行符。
  2. scanf后的换行符残留:比如输入选项后按回车,这个换行符会留在输入缓冲区里,导致后续输入直接读到空内容,需要用getchar()清理。
  3. 值传递的坑:原来的signUp函数里age是值传递,函数内修改的只是副本,主函数里的age不会被更新,换成指针参数才能传递真实输入的年龄。
  4. 文件写入错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:11:59