C中的身份验证(从给定文件中读取和检查)

时间:2017-02-25 14:58:39

标签: c file struct linked-list

我在下面创建了代码。我需要做的是我需要从用户那里获取和输入(用户名和密码),我需要用文件检查我输入的内容。问题迫使我不要复制整个.txt文件一次。 .txt文件的转换如下:

root
jfl34jgf
ben
12b43
stella
ldfo421
kate
jfd45g
bill
iu3556
guest
1234
test
1234

所以我想要获取所有用户名,将它们放入列表中,然后使用输入检查每个用户名。我创建了一个结构,其中包括用户名,用户名结束的位置(使用ftell())和指向下一个元素的下一个指针。正如您所看到的那样,文本的格式与用户名相同,另一种是密码。所以密码就在用户名之后。如果名称的比较给我的真实,那么对每个用户名使用ftell()。我可以检查密码检查。

这是我的代码,直到现在。

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

struct names
{
    char name[20];
    int pos;
    struct names *next;
};
typedef struct names Names;

void create_list(Names *l, char *temp1, int pos)
{
    Names *temp;
    temp=(Names*)malloc(1*sizeof(Names));
    temp->next=NULL;

    strcpy(temp->name, temp1);
    temp->pos=pos;
    temp->next=l;
    printf("%s ", temp->name);

    l=temp;
    printf("%s\n", l->name);
}

void create_list_from_File(FILE *fp, Names *l)
{
    char ch;
    int i=0, check=0, pos;

    char temp1[20];
    temp1[0]='\0';

    while(1)
    {
        if(check==1)
            break;

        while((ch=fgetc(fp))!='\n')
        {
            temp1[i]=ch;
            i++;
        }
        temp1[i]='\0';

        pos=ftell(fp)+1;

        create_list(l,temp1, pos);

        while((ch=fgetc(fp))!='\n')
        {
            if(ch==EOF)
            {
                printf("EOF ");
                check=1;
                break;
            }
        }
        i=0;
    }
}

void display(Names *l)
{
    Names *cursor;

    cursor=l;
    while (cursor!=NULL)
    {
        printf("%s\n", cursor->name);
        cursor=cursor->next;
    }
}


int main()
{
    char usern[20][20];
    char passw[20];
    FILE *fp;
    Names l;
    l.next=NULL;
    char c;
    int i=0;

    fp=fopen("users.txt", "r");

    if(fp==NULL)
    {
        printf("File not opened!\n");
        exit(1);
    }

    create_list_from_File(fp, &l);

    display(&l);


    /*  fgets(usern, 20, stdin);
    usern[strlen(usern)-1]='\0';

    while(strcmp(usern, "exit")!=0)
    {
    fgets(passw,20, stdin);
    passw[strlen(passw)-1]='\0';
    check(fp, usern, passw);
    }
    */
    return 0;
}

现在我看不到链接列表中的内容。我正确地从文件中获取字符串(打印用户名),但是当我尝试打印列表时,它只给了我一些奇怪的值。非常感谢帮助。

2 个答案:

答案 0 :(得分:0)

提供的源代码在管理链表时会出现经典错误。修改函数内部指针的内容作为值传递时仅作为局部效果,并且不影响调用函数中的值。

问题 - 修改函数Names *lcreate_list()的值。

函数create_list()在列表前面添加一个新节点Names *temp;,通过仅修改第一个节点来提高性能。

  • 新节点指向第一个temp->next=l;
  • 然后新节点成为第一个l=temp;

当打印本地值时,似乎没问题。

但是,赋值l=temp;仅在函数内部可用(赋值给本地Names *l指针)并且当返回到调用函数create_list_from_File()l没有'改变。

解决方案1 ​​ - 修改l->next的值是最快的解决方案。

main()中,已声明一个起始Names l;,其中包含l.next=NULL;赋值(列表为空)。

create_list()函数中,赋值为:

strcpy(temp->name, temp1);
temp->pos=pos;
// assigning to the next pointer
temp->next=l->next;
printf("%s ", temp->name);

// modify the next pointer
l->next=temp;
printf("%s\n", l->next->name);

而不是:

strcpy(temp->name, temp1);
temp->pos=pos;
temp->next=l;
printf("%s ", temp->name);

l=temp;
printf("%s\n", l->name);

要完成,对于最短的解决方案,函数display()应从作为第一个节点的l->next开始。

void display(Names *l)
{
    Names *cursor;

    cursor=l->next;
    while (cursor!=NULL)
    {
        printf("%s\n", cursor->name);
        cursor=cursor->next;
    }
}

答案 1 :(得分:0)

感谢@ J.Piquard提供上述帮助。我设法解决了这个问题。我发布下面的代码,代码可以在上面的.txt文件中测试。首先,用户输入输入,然后输入用户名,后跟密码。假设用户名输入始终是正确的,但检查用户名并不是那么难。

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

struct names
{
    char name[20];
    int pos;
    struct names *next;
};

typedef struct names Names;

Names *create_list(Names *l, char *temp1, int pos)
{
    Names *temp;
    temp=(Names*)malloc(1*sizeof(Names));
    strcpy(temp->name, temp1);
    temp->pos=pos;
    temp->next=l;

    return temp;

}

Names * create_list_from_File(FILE *fp)
{
    char ch;
    int i=0, check=0, pos;

    Names *l=NULL;

    char temp1[20];
    temp1[0]='\0';

    while(1)
    {
        if(check==1)
            break;

        while((ch=fgetc(fp))!='\n')
        {
            temp1[i]=ch;
            i++;
        }
        temp1[i]='\0';

        pos=ftell(fp)+1;
        l=create_list(l,temp1, pos);

        while((ch=fgetc(fp))!='\n')
        {
            if(ch==EOF)
            {
                check=1;
                break;
            }
        }
        i=0;
    }
    return l;
}



int check_usrn(char *s, Names *l, int *i)
{
    int flag=0;
    Names *cursor=l;
    *i=0;

    while (cursor!=NULL)
    {
        if(strcmp(cursor->name, s)==0)
        {
            flag=1;
            break;
        }
        cursor=cursor->next;
        (*i)++;
    }
    return flag;
}

int check_passw(FILE *fp, Names *l, char *passw, int *i)
{
    Names * cursor;

    cursor=l;
    int m=0, flag=0;
    char c, temp[20];

    while(m!=*i)
    {
        cursor=cursor->next;
        m++;

    }
    m=0;

    fseek(fp, cursor->pos-1, SEEK_SET);

    while((c=fgetc(fp))!='\n')
    {
        if(c==EOF)
            break;
        temp[m]=c;
        m++;
    }

    temp[m]='\0';

    if(strcmp(passw, temp)==0)
        flag=1;

    return flag;
}


int main()
{
    char usern[20];
    char passw[20];
    char file_name[20];
    FILE *fp;
    Names *l=NULL;
    int i=0;

    fgets(file_name, 20, stdin);
    file_name[strlen(file_name)-1]='\0';

    fp=fopen(file_name, "r");

    if(fp==NULL)
    {
        printf("File not opened!\n");
        exit(1);
    }

    l=create_list_from_File(fp);


    while(strcmp(usern, "exit")!=0)
    {
        fgets(usern, 20, stdin);
        usern[strlen(usern)-1]='\0';

        if(check_usrn(usern, l, &i)==1)
        {
            fgets(passw, 20, stdin);
            passw[strlen(passw)-1]='\0';

            if(check_passw(fp ,l, passw, &i)==1)
                printf("Access to user %s is granted.\n", usern);

            else
                printf("Access to user %s is denied.\n", usern);
        }
    }

    printf("Exiting ...\n");
    fclose(fp);
    return 0;
}