C 语言实战:3 次机会密码验证系统(字符串处理 + 边界校验)

密码验证是 C 语言字符串处理的经典入门场景,核心考察fgets输入、换行符处理、strlen长度对比、strcmp字符对比等知识点。本文基于完整的密码验证系统代码,拆解 “设置密码→验证密码→次数限制→结果反馈” 的全流程,详解字符串处理的关键细节与避坑技巧。

一、系统核心需求与设计思路

1. 核心需求

  • 第一步:用户设置初始密码(支持含空格的密码,避免scanf的局限性);
  • 第二步:用户输入密码验证,最多 3 次机会;
  • 第三步:密码错误时提示剩余次数,3 次错误直接退出;密码正确则验证通过。

2. 核心技术点

技术点 作用
fgets 读取带空格的密码(scanf遇空格终止,不适用)
strcspn 去除fgets读取的换行符(避免密码包含\n导致对比失败)
strlen 先对比密码长度(快速排除明显错误的密码)
strcmp 逐字符对比密码内容(返回 0 表示完全一致)
循环 + 计数器 控制 3 次验证机会,错误时递减并提示剩余次数

二、完整代码解析(带详细注释)

c

运行

/******************************
*文件名称:7.Password_3times.c
*作者:czy
*邮箱:caozhiyang_0613@163.com
*创建日期:2025/12/25
*修改日期:
*文件功能:密码验证系统,设置初始密码后验证,最多3次错误机会
*核心思路:
*  1. fgets读取密码(支持空格),strcspn去除换行符;
*  2. 先对比密码长度,再用strcmp逐字符对比;
*  3. 循环控制3次验证机会,错误时递减并提示剩余次数;
*  4. pivot标志位标记密码是否正确,最终反馈验证结果。
*****************************/
#include<stdio.h>
#include<string.h>

int main()
{
    char a[100];  // 存储用户设置的初始密码
    char b[100];  // 存储验证时输入的密码
    int pivot = 0;  // 密码正确标志:1=正确,0=错误
    int chance = 3; // 初始验证机会:3次
    
    // 1. 设置初始密码
    printf("===== 密码验证系统 =====\n");
    printf("请设置初始密码:");
    // fgets读取输入(最多99个字符+1个'\0'),支持含空格的密码
    fgets(a, sizeof(a), stdin);
    // 去除fgets自动读取的换行符(关键!否则密码会包含\n)
    a[strcspn(a, "\n")] = '\0'; 
    
    // 2. 密码验证循环(3次机会)
    printf("\n请开始验证密码(共%d次机会):\n", chance);
    while (chance > 0)
    {
        printf("请输入密码:");
        fgets(b, sizeof(b), stdin);
        b[strcspn(b, "\n")] = '\0'; // 同样去除输入密码的换行符
        
        // 3. 密码验证逻辑:先判长度(快速过滤),再判内容
        if (strlen(a) == strlen(b)) // 长度不同直接判定错误
        {
            // strcmp返回0表示两个字符串完全一致
            if (strcmp(a, b) == 0)
            {
                pivot = 1; // 标记密码正确
                break;      // 验证通过,退出循环
            }
        }
        
        // 4. 密码错误:消耗机会,提示剩余次数
        chance--;
        if (chance > 0)
        {
            printf("密码错误!您还有%d次输入机会哦\n", chance);
        }
        else
        {
            printf("密码错误!输入错误,给你机会,你也不中用啊,您没有机会了哦\n");
        }
    }
    
    // 5. 最终验证结果反馈
    if (pivot == 1)
    {
        printf("输入正确!验证通过✅\n");
    }
    return 0;
}

三、核心模块拆解

1. 密码输入与换行符处理(关键避坑点)

c

运行

fgets(a, sizeof(a), stdin);
a[strcspn(a, "\n")] = '\0';
  • fgets的优势:相比scanf("%s", a)fgets支持读取含空格的密码(比如密码是123 abc),且能限制读取长度(避免数组越界);
  • 换行符处理的必要性:fgets会把用户按的Enter键(\n)也读取到字符串中,若不删除,设置的密码会包含\n,后续验证时即使输入相同字符也会判定错误;
  • strcspn(a, "\n")的作用:返回a中第一个\n的位置,将该位置赋值为'\0',相当于 “截断” 掉换行符。

2. 密码验证逻辑(先长度后内容)

c

运行

if (strlen(a) == strlen(b))
{
    if (strcmp(a, b) == 0)
    {
        pivot = 1;
        break;
    }
}
  • 先对比长度:如果两次输入的密码长度不同,无需逐字符对比,直接判定错误,提升验证效率;
  • strcmp对比规则:逐字符比较 ASCII 码值,直到遇到不同字符或'\0'
    • 返回 0:所有字符都相同(密码正确);
    • 返回正数:第一个不同字符的 ASCII 码差值为正;
    • 返回负数:第一个不同字符的 ASCII 码差值为负。

3. 验证机会控制

c

运行

chance--;
if (chance > 0)
{
    printf("密码错误!您还有%d次输入机会哦\n", chance);
}
else
{
    printf("密码错误!输入错误,给你机会,你也不中用啊,您没有机会了哦\n");
}
  • chance--:每次密码错误后,剩余机会减 1;
  • 分支提示:剩余机会 > 0 时提示剩余次数,=0 时提示无机会,用户体验更友好。

四、运行结果示例

示例 1:密码正确(1 次验证通过)

plaintext

===== 密码验证系统 =====
请设置初始密码:123456

请开始验证密码(共3次机会):
请输入密码:123456
输入正确!验证通过✅

示例 2:密码错误(3 次机会用完)

plaintext

===== 密码验证系统 =====
请设置初始密码:abc123

请开始验证密码(共3次机会):
请输入密码:123abc
密码错误!您还有2次输入机会哦
请输入密码:abc12
密码错误!您还有1次输入机会哦
请输入密码:abc456
密码错误!输入错误,给你机会,你也不中用啊,您没有机会了哦

示例 3:密码含空格(验证通过)

plaintext

===== 密码验证系统 =====
请设置初始密码:my password 123

请开始验证密码(共3次机会):
请输入密码:my password 123
输入正确!验证通过✅

五、优化与扩展建议

1. 现有代码优化点

  • 密码长度限制:可增加密码长度校验(比如要求密码长度≥6),避免设置空密码;
  • 隐藏输入密码:结合getch函数(Windows)或termios(Linux)实现密码输入时隐藏(不显示输入的字符),提升安全性;
  • 重复设置密码:增加 “确认密码” 步骤,要求用户输入两次初始密码,避免设置错误;
  • 输入空密码处理:若用户直接按 Enter 设置 / 验证密码,提示 “密码不能为空”,重新输入。

2. 功能扩展

  • 密码强度检测:设置密码时检测复杂度(是否包含数字、字母、特殊字符);
  • 错误次数锁定:3 次错误后不仅退出,还提示 “账号锁定 5 分钟”;
  • 密码修改功能:验证通过后,提供 “修改密码” 选项。

六、核心知识点总结

1. 字符串输入

  • fgets是读取带空格字符串的首选,需注意处理换行符;
  • strcspn是去除换行符的简洁方法(替代手动循环查找\n)。

2. 字符串对比

  • strlen获取字符串长度(不包含'\0'),用于快速过滤长度不符的密码;
  • strcmp是字符串内容对比的核心函数,返回 0 表示完全一致。

3. 循环与状态控制

  • 用计数器chance控制验证次数,递减逻辑简单且易维护;
  • 用标志位pivot标记验证结果,避免循环内直接输出最终结果,逻辑更清晰。

这个密码验证系统虽然简单,但覆盖了 C 语言字符串处理的核心知识点,是入门字符串操作的绝佳案例。掌握这些细节后,可轻松扩展为更复杂的登录系统、密码管理工具等。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐