2017-02-25 5 views
-2

以下のコードを作成しました。私がする必要があるのは、ユーザーから取得して入力する必要がある(ユーザー名とパスワード)ので、入力したファイルを確認する必要があります。この問題は、一度に.txtファイル全体をコピーしないようにします。Cでの認証(指定されたファイルからの読み取りとチェック)

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

だから私は、すべてのユーザー名を取得することを考えて、リストにそれらを入れた後、入力してそれらの一つ一つをチェックしていた:.txtファイルは、次のように変換されます。ユーザ名、ユーザ名が終わる位置(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; 
} 

現在、私はリンクされたリストの中に何も見ません。ファイルから文字列を正しく取得しています(ユーザー名が表示されます)が、リストを印刷しようとするとちょっと変わった値が返されます。ヘルプは非常に高く評価されます。

答えて

0

提供されたソースコードは、リンクされたリストを管理する際に古典的なエラーを表示します。値としてローカルエフェクトとして渡されたときに関数内のポインタの内容を変更し、呼び出し元関数の値には影響しません。

問題 - 機能create_list()Names *lの値を変更しています。

機能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; 
    } 
} 
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; 
} 
関連する問題