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

C语言中strcmp()未按预期返回0:用户名密码验证异常排查

密码对比异常问题排查与修复

问题场景

对比用户输入的用户名和密码,待验证的字符串从文件userdata.txt读取。目前用户名对比正常,但密码对比时strcmp()始终无法返回0,导致校验失败。

原代码

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

const int MAX_SIZE = 100;

int main()
{
    FILE *fp;
    char *filename = "userdata.txt";
    char arr[100][MAX_SIZE];
    
    //open for writing
    fp = fopen(filename, "r");
    
    //verify open
    if(fp == NULL)
    {
        printf("%s does not exist", filename);
        return 0;
    }

    int index = 0;

    //read file into array
    while(fgets(arr[index], MAX_SIZE, fp) != NULL) 
    {
        index++;
    }
    
    //username input
    char username[100];
    printf("Username: ");
    scanf("%s", username);

    //password input
    char password[100];
    printf("Password: ");
    scanf("%s", password);
    
    
    int check1 = 0;
    int check2 = 0;
    int x;
    for (int i = 0 ; i<index ; i++)
    {
        char *token = strtok(arr[i], " ");
       
        while (token != NULL)
        {
            x = strcmp(token,username);
            printf("%d\n",x);
            printf("%s %s\n",token,username);
            if(!strcmp(token,username))
            {
                check1 = 1;
            }
            
            token = strtok(NULL, " ");
            x = strcmp(token,username);
            printf("%d\n",x);
            printf("%s %s\n",token,password);
            if(!strcmp(token,username))
            {
                check2 = 1;
            }
            
            token = strtok(NULL, " ");
            
            if(check1&&check2)
            {
                printf("The amount is: %s\n",token);
                return 0;
            }
    
            token = strtok(NULL, " ");
            
            check1=0;
            check2=0;
        }
    }
    printf("Username/Password mismatch!!!\n");
    return 0;
}

控制台输出

Username: user1
Password: password1
0
user1 user1
-5
password1 password1
1
user2 user1
-5
password2 password1
2
user3 user1
-5
password3 password1
3
user4 user1
-5
password4 password1
4
user5 user1
-5
password5 password1
5
user6 user1
-5
password6 password1
Username/Password mismatch!!!

错误原因

  1. fgets读取的字符串包含换行符:fgets()会将文件中的换行符\n一并读入到数组元素中,导致分割后的密码字符串末尾带有\n。而scanf("%s", password)读取用户输入时,会自动忽略换行符,因此两个字符串实际内容不一致,strcmp()返回非0值。
  2. 密码校验的对比对象错误:代码中校验密码时,错误地使用strcmp(token, username)进行对比,正确的应该是strcmp(token, password)。这个逻辑错误直接导致check2永远无法被设置为1,最终无法触发校验成功的分支。

修复后的代码

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

const int MAX_SIZE = 100;

int main()
{
    FILE *fp;
    char *filename = "userdata.txt";
    char arr[100][MAX_SIZE];
    
    fp = fopen(filename, "r");
    if(fp == NULL)
    {
        printf("%s does not exist\n", filename);
        return 0;
    }

    int index = 0;
    // 读取文件时去除换行符
    while(fgets(arr[index], MAX_SIZE, fp) != NULL) 
    {
        // 去掉fgets读取的换行符
        arr[index][strcspn(arr[index], "\n")] = '\0';
        index++;
    }
    fclose(fp); // 关闭文件,避免资源泄漏
    
    char username[100];
    printf("Username: ");
    scanf("%s", username);

    char password[100];
    printf("Password: ");
    scanf("%s", password);
    
    for (int i = 0 ; i<index ; i++)
    {
        char *user_token = strtok(arr[i], " ");
        if (user_token == NULL) continue;
        
        char *pwd_token = strtok(NULL, " ");
        if (pwd_token == NULL) continue;
        
        char *amount_token = strtok(NULL, " ");
        if (amount_token == NULL) continue;
        
        // 同时校验用户名和密码
        if (strcmp(user_token, username) == 0 && strcmp(pwd_token, password) == 0)
        {
            printf("The amount is: %s\n", amount_token);
            return 0;
        }
    }
    printf("Username/Password mismatch!!!\n");
    return 0;
}

修复说明

  • 用strcspn(arr[index], "\n")定位换行符位置,将其替换为字符串结束符\0,去除fgets读取的换行符。
  • 简化strtok的使用逻辑:每一行固定分割出用户名、密码、金额三个字段,直接依次获取后对比,避免嵌套循环的逻辑混乱。
  • 修正密码校验的对比对象,改为strcmp(pwd_token, password)。
  • 添加fclose(fp)关闭文件,避免资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:43:18