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

基于strcmp的多字符串验证登录代码运行异常问题排查

登录功能C代码问题排查与修复

问题描述

编写的登录功能代码在输入用户名和密码后直接终止,无法执行后续逻辑,代码如下:

typedef struct uLogin
{
    char user1,user2,user3,user4;
} uLogin;


void loginUser() {

    uLogin x1;
    int i, m, n;

    char pass_list[20] = "12345678",name[10],pass[10];
    x1.user1 = "DSET2G1";
    x1.user2 = "DSET2G2";
    x1.user3 = "DSET2G3";
    x1.user4 = "DSET2G4";

    printf("\nEnter username: ");
    scanf("%s",&name);
    fflush(stdout);

    printf("\nEnter Password :");
    scanf("%s",&pass);
    fflush(stdout);

    m = (strcmp(name,x1.user1)==0 && strcmp(name,x1.user2)==0 && strcmp(name,x1.user3)==0 && strcmp(name,x1.user4)==0);
    n = strcmp(pass,pass_list);

    if(m == 0 && n == 0)
    {
        system("CLS");
        printf("Hello");
    }
    else
    {
        system("CLS");
        printf("Bye");
    }
}

核心问题与原因

  • 结构体成员类型错误:uLogin结构体中的user1到user4被定义为char类型,单个char仅能存储一个字符,无法容纳完整字符串。将字符串字面量(如"DSET2G1")赋值给char变量,本质是把字符串的首地址(指针值)强制转换为char,直接破坏内存布局,触发未定义行为。
  • scanf传参错误:name和pass是字符数组名,本身就是指向数组首元素的指针,不需要加&。使用scanf("%s",&name)会传入数组的地址(指针的指针),导致scanf向错误内存地址写入数据,直接引发程序崩溃或异常终止。
  • 用户名匹配逻辑完全错误:代码用&&连接四个strcmp判断,意味着输入的用户名必须同时等于四个不同的字符串,这在逻辑上不可能成立,m的值永远为0,后续判断逻辑完全失效。
  • 缺少必要头文件:strcmp函数需要<string.h>头文件,system函数需要<stdlib.h>头文件,未包含这些头文件会导致编译器无法识别函数,引发未定义行为。

修正后的代码

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

// 修改结构体成员为字符串指针类型,支持存储字符串地址
typedef struct uLogin
{
    const char* user1;
    const char* user2;
    const char* user3;
    const char* user4;
} uLogin;

void loginUser() {
    uLogin x1;
    int is_valid_user = 0;
    int is_valid_pass = 0;

    char pass_list[20] = "12345678", name[10], pass[10];
    // 正确赋值字符串指针
    x1.user1 = "DSET2G1";
    x1.user2 = "DSET2G2";
    x1.user3 = "DSET2G3";
    x1.user4 = "DSET2G4";

    printf("\nEnter username: ");
    // 数组名直接作为参数,无需加&
    scanf("%s", name);
    fflush(stdout);

    printf("\nEnter Password :");
    scanf("%s", pass);
    fflush(stdout);

    // 修改匹配逻辑:用户名匹配任意一个合法用户即有效
    if (strcmp(name, x1.user1) == 0 || 
        strcmp(name, x1.user2) == 0 || 
        strcmp(name, x1.user3) == 0 || 
        strcmp(name, x1.user4) == 0) {
        is_valid_user = 1;
    }
    is_valid_pass = (strcmp(pass, pass_list) == 0);

    if (is_valid_user && is_valid_pass) {
        system("CLS");
        printf("Hello");
    } else {
        system("CLS");
        printf("Bye");
    }
}

关键修改说明

  1. 补充<string.h>、<stdlib.h>头文件,确保标准函数能被正确识别。
  2. 将结构体成员改为const char*类型,用于存储字符串字面量的地址,正确存储用户名。
  3. 移除scanf参数中的&,直接传入数组名,保证写入地址正确。
  4. 将用户名匹配逻辑从&&改为||,只要输入用户名匹配任意一个合法用户即判定为有效。
  5. 变量命名更具语义化,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:55:12