系统密码文件读取与函数

哭了c语言系统,save me!
其中设置了一个判断密码是否正确的函数,就是我原来有一个账号密码文本文档,读取后想判断是否与用户输入id,password相同,
相同则返回1,不同则返回0。
如果单个打印能打出来但是就是不返回1.

typedef struct password{
    char id[8];
    char pass_word[8];
    struct password *pw_next;
}Password;
int Password_confirm(char id[],char pass[]){
    int i;
    Password pw_temp={"\t","\t"};
    FILE*fp;
    char filename[30] = { "账号密码管理.txt" };
        if ((fp = fopen(filename, "rb+")) == NULL)
        {
            printf("can not open!\n");
            getchar();
            exit(0);
        }    
    else{
        int j;
        for(j=0;j<=100;j++){
            fscanf(fp,"%s\t%s\n",&pw_temp.id,&pw_temp.pass_word);
            if ((strcmp(pw_temp.id, id) == 0)&& (strcmp(pw_temp.pass_word, pass) == 0)){
                fclose(fp);
                return 1;
            }
        }
        fclose(fp);
        return 0;
    } 
}

文本文档格式为utf-8:1111加上一个tab键加上a
9999 a
1001 b
1002 c
1003 d
1004 e
1005 f
1006 g
1007 h
1008 i
1009 g
1010 k
1011 l
1012 m
1013 n
1014 o
1015 p
1016 q
1017 r
1018 s
1019 t
1020 u
0001 v
0002 w
0003 2
0004 3
0005 4
0006 5
0007 6
0008 7
0009 8
0010 x
0011 y
0012 z

我看下

img

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

typedef struct password{
    char id[8];
    char pass_word[8];
    struct password *pw_next;
}Password;

int Password_confirm(char id[],char pass[]){
    int i;
    Password pw_temp={"\t","\t"};
    FILE*fp;
    char filename[30] = { "账号密码管理.txt" };

    if ((fp = fopen(filename, "r")) == NULL)
    {
        printf("can not open!\n");
        getchar();
        exit(0);
    }    
    else{
        while (fscanf(fp, "%s\t%s", pw_temp.id, pw_temp.pass_word) != EOF) {
            if ((strcmp(pw_temp.id, id) == 0) && (strcmp(pw_temp.pass_word, pass) == 0)) {
                fclose(fp);
                return 1;
            }
        }
        fclose(fp);
        return 0;
    } 
}

int main(){
    char id[8], pass[8];
    printf("请输入您的账号:\n");
    scanf("%s", id);
    getchar();
    printf("请输入您的密码:\n");
    scanf("%s", pass);
    if (Password_confirm(id, pass)) {
        printf("返回值是%d\n", Password_confirm(id, pass));
        printf("密码正确!\n");
    } else {
        printf("返回值是%d\n", Password_confirm(id, pass));
        printf("密码错误!\n");
    }
    return 0;
}


该回答引用ChatGPT4与博主@晓码自在合作编写:

根据你的代码和文本文档情况,这里可能出现的问题有:

  1. fscanf读取电话号码时,如果碰到空格会认为整个电话号码字段结束,所以电话号码如果包含空格,会读取失败。

  2. strcmp判断字符串相等时,如果遇到\t制表符,也会认为字符串不相等,导致匹配失败。

  3. 文本文件如果编码不是utf-8,中文可能导致读取异常。

所以,这里有几个改进意见:

  1. fscanf读取字段时,可以使用%[^\t]格式,指定任意字符直到遇到制表符为止。这样可以正确读取包含空格的电话号码。

  2. strcmp比较前,可以去除字符串中含有的制表符\t,然后再比较。这样可以正确判断相等的字符串。

  3. 明确指定文本文件编码为utf-8,或者使用fgetwc等宽字符函数读取。

改进后的代码如下:

c
typedef struct password{
    char id[8];
    char pass_word[20];   // 增加密码字段长度
    struct password *pw_next;
}Password;

int Password_confirm(char id[],char pass[]){
    // ...
    FILE*fp;
    fopen(filename, "rb+");  // 明确以二进制读写模式打开
    
    // fscanf读取电话号码
    fscanf(fp,"%s %[^\t]\n",&pw_temp.id,&pw_temp.pass_word);  
    
    // strcmp前去除制表符
    int i,j;
    for(i=0; pw_temp.id[i]; i++) {
        if(pw_temp.id[i] == '\t') pw_temp.id[i] = '\0';
    }
    for(j=0; pw_temp.pass_word[j]; j++) {
        if(pw_temp.pass_word[j] == '\t') pw_temp.pass_word[j] = '\0';
    }
    
    if(strcmp(pw_temp.id, id) == 0 && strcmp(pw_temp.pass_word, pass) == 0)
        return 1;
}

以上改进可以很好解决你提到的该函数无法返回1的问题。