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

C语言简易登录注册系统编译错误求助及功能开发需求

Hey there! Let's work through fixing your code and getting that login/register system up and running. First, let's tackle the compilation error you're hitting, then we'll fix other bugs and add the validation your assignment requires.

1. Fix the "storage size of ‘l’ isn’t known" Error

In C, you need to declare a struct before you use it. Your struct login definition was sitting after the login() function, so when the compiler reached struct login l; inside login(), it had no idea what that type was yet.

Fix this by moving the struct definition to the top, right after your includes:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// Move struct definition here so all functions can see it
struct login {
    char fname[30];
    char lname[30];
    char username[30];
    char password[20];
}; // Don't forget the semicolon at the end!

Also, notice the missing semicolon at the end of your original struct definition—another common gotcha that would cause compilation issues.

2. Add Function Return Types

Your login() and registration() functions didn't have return types specified. In standard C, this isn't allowed—declare them as void since they don't need to return a value:

void login() { ... }
void registration() { ... }

3. Fix Input Handling Bugs

Your input code had several issues that would break functionality even after compilation:

  • scanf("%c", ...) is wrong: You used %c (which reads a single character) to read full strings. Use fgets for more robust input (and handle the newline character it captures):
    fgets(l.fname, 30, stdin);
    l.fname[strcspn(l.fname, "\n")] = '\0'; // Strip the newline character
    
  • scanf leaves leftover newlines: After using scanf("%d", &option) in main(), the newline character stays in the input buffer, which would cause the next fgets to read an empty line. Fix this by flushing the buffer:
    scanf("%d",&option);
    while(getchar() != '\n'); // Clear leftover newline
    
  • Unused variable: In registration(), you declared firstname[15] but never used it—you meant to use l.fname in the welcome message.

4. Fix File Handling Issues

  • Login file existence check: When opening the login file in login() with "r", if the file doesn't exist (no users registered yet), fopen returns NULL—accessing this will crash your program. Add a safety check:
    FILE *log = fopen("login.txt","r");
    if(log == NULL) {
        printf("\nNo users registered yet! Please register first.\n");
        return;
    }
    
  • Registration overwrites users: Using "w" in fopen for registration will erase all existing users. Use "a" (append mode) instead to add new users to the file:
    FILE *log = fopen("login.txt","a");
    
  • Login loop logic: Your current login loop printed "Incorrect Login Details" for every user that didn't match. Instead, track if we found a matching user, then print the result once after the loop:
    int login_success = 0;
    while(fread(&l,sizeof(l),1,log)) {
        if(strcmp(username,l.username)==0 && strcmp(password,l.password)==0) {
            login_success = 1;
            break; // Exit loop once we find a match
        }
    }
    if(login_success) {
        printf("\nSuccessful Login\n");
    } else {
        printf("\nIncorrect Login Details\n");
    }
    

5. Add Input Validation (Your Assignment Requirement)

Let's add functions to validate username length and password complexity:

// Check username length (<=30 chars)
int validate_username(char *user) {
    if(strlen(user) > 29) { // Since array is 30, max length is 29 + null terminator
        printf("Username too long! Max 30 characters.\n");
        return 0;
    }
    return 1;
}

// Check password meets requirements: min 8 chars, has upper, lower, number, special char
int validate_password(char *pass) {
    int has_upper = 0, has_lower = 0, has_num = 0, has_special = 0;
    int len = strlen(pass);
    
    if(len < 8) {
        printf("Password too short! Min 8 characters.\n");
        return 0;
    }
    
    for(int i=0; i<len; i++) {
        if(isupper(pass[i])) has_upper = 1;
        else if(islower(pass[i])) has_lower = 1;
        else if(isdigit(pass[i])) has_num = 1;
        else if(!isalnum(pass[i])) has_special = 1; // Special chars are non-alphanumeric
    }
    
    if(!has_upper || !has_lower || !has_num || !has_special) {
        printf("Password must contain uppercase, lowercase, number, and special character!\n");
        return 0;
    }
    return 1;
}

Then call these functions in registration() before writing to the file:

// After getting username and password
if(!validate_username(l.username) || !validate_password(l.password)) {
    fclose(log);
    return;
}

Full Modified Code

Here's the complete fixed code with all the above changes:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

struct login {
    char fname[30];
    char lname[30];
    char username[30];
    char password[20];
};

int validate_username(char *user) {
    if(strlen(user) > 29) {
        printf("Username too long! Max 30 characters.\n");
        return 0;
    }
    return 1;
}

int validate_password(char *pass) {
    int has_upper = 0, has_lower = 0, has_num = 0, has_special = 0;
    int len = strlen(pass);
    
    if(len < 8) {
        printf("Password too short! Min 8 characters.\n");
        return 0;
    }
    
    for(int i=0; i<len; i++) {
        if(isupper(pass[i])) has_upper = 1;
        else if(islower(pass[i])) has_lower = 1;
        else if(isdigit(pass[i])) has_num = 1;
        else if(!isalnum(pass[i])) has_special = 1;
    }
    
    if(!has_upper || !has_lower || !has_num || !has_special) {
        printf("Password must contain uppercase, lowercase, number, and special character!\n");
        return 0;
    }
    return 1;
}

void login() {
    char username[30],password[20];
    FILE *log = fopen("login.txt","r");
    
    if(log == NULL) {
        printf("\nNo users registered yet! Please register first.\n");
        return;
    }
    
    struct login l;
    printf("\nPlease Enter your login credentials below\n\n");
    printf("Username: ");
    fgets(username, 30, stdin);
    username[strcspn(username, "\n")] = '\0';
    
    printf("\nPassword: ");
    fgets(password, 20, stdin);
    password[strcspn(password, "\n")] = '\0';
    
    int login_success = 0;
    while(fread(&l,sizeof(l),1,log)) {
        if(strcmp(username,l.username)==0 && strcmp(password,l.password)==0) {
            login_success = 1;
            break;
        }
    }
    
    if(login_success) {
        printf("\nSuccessful Login\n");
    } else {
        printf("\nIncorrect Login Details\n");
    }
    
    fclose(log);
}

void registration() {
    FILE *log = fopen("login.txt","a");
    if(log == NULL) {
        printf("Error opening file!\n");
        return;
    }
    
    struct login l;
    printf("\nWelcome to your online course provider. We need to enter some details for registration.\n\n");
    
    printf("Enter First Name: ");
    fgets(l.fname, 30, stdin);
    l.fname[strcspn(l.fname, "\n")] = '\0';
    
    printf("Enter Surname: ");
    fgets(l.lname, 30, stdin);
    l.lname[strcspn(l.lname, "\n")] = '\0';
    
    printf("\nThank you.\nNow please choose a username and password as credentials for system login.\n");
    printf("Ensure the username is no more than 30 characters long.\n");
    printf("Ensure your password is at least 8 characters long and contains lowercase, uppercase, numerical and special character values.\n");
    
    printf("\nEnter Username: ");
    fgets(l.username, 30, stdin);
    l.username[strcspn(l.username, "\n")] = '\0';
    
    printf("\nEnter Password: ");
    fgets(l.password, 20, stdin);
    l.password[strcspn(l.password, "\n")] = '\0';
    
    // Validate inputs
    if(!validate_username(l.username) || !validate_password(l.password)) {
        fclose(log);
        return;
    }
    
    fwrite(&l,sizeof(l),1,log);
    fclose(log);
    
    printf("\nConfirming details...\n...\nWelcome, %s!\n\n", l.fname);
    printf("Registration Successful!\n");
    printf("Press any key to continue...");
    getchar();
    system("CLS");
    login();
}

int main() {
    int option;
    printf("Press '1' to Register\nPress '2' to Login\n\n");
    scanf("%d",&option);
    while(getchar() != '\n'); // Clear input buffer
    
    if(option == 1) {
        system("CLS");
        registration();
    } else if(option == 2) {
        system("CLS");
        login();
    } else {
        printf("Invalid option!\n");
    }
    
    return 0;
}

This code should compile cleanly, handle input correctly, avoid file crashes, and include the validation your assignment asks for. Let me know if you need clarification on any part!

内容的提问来源于stack exchange,提问作者slowlearner02

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:37:41