当前位置: 代码迷 >> C语言 >> 简易用户验证程序设计问题
  详细解决方案

简易用户验证程序设计问题

热度:165   发布时间:2006-02-25 22:51:00.0
简易用户验证程序设计问题

----------------------
稍微有点长

用户验证程序
1. 从外部文件中获取用户的用户名以及用户密码信息
2. 提示用户输入用户名及密码
3. 与读入的用户信息进行比对
4. 验证由此用户后显示加密文件,否则退出

出现问题:
1. 在比对程序match()中出错,疑为指针赋值时出错
2. 某些地方写的冗繁,不够简练

需要建立 验证后的输出文件message.txt 和用户信息
文件userdate.txt 内部格式为 name: password
----------------------
/* CheckUser.c
* -----------------------
* This program is used to show the coded message
* on the screen by reading the user infomation outside.
* It aims at studying the structures and read fomated
* input file.
*/

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

/*
* constants
* ------------
* Buffer -- Maximum input string length
* MaxNameLen --Maximum input name length
* MaxPasswordLen --Maximum input password length
* MaxUsers --Maximum users number
*/

#define Buffer 120
#define MaxNameLen 25
#define MaxPasswordLen 16
#define MaxUsers 6

/* bool definition */
typedef enum {FALSE, TRUE} bool;

/* Date structures */

/* Type: userT
* --------------
* This structure is used to provide the space of a user's
* infomation. For the users' number is unkown, so it defines
* as a pointer type.
*/

typedef struct {
char *name;
char *password;
} *userT;

/* Type userDB
* ---------------
* This structure is used to record the datebase, which is a
* pointer containing users' information and the coded message
* file also has the valid number of the users
*/

typedef struct {
userT userdate[MaxUsers+1];
FILE *message;
int nusers;
} *userDB;

/* Private function declarations */

static userDB ReadDateBase(void);
static void ReadUserInfo(FILE *infile, userDB userdatebase);
static void ProcessDateBase(userDB userdatebase);
static userT GetUserInfo(void);
static bool match(userT userinfo, userDB userdatebase);
static void Decipher(FILE *message);
static void CopyFile(FILE *outfile, FILE *infile);
static FILE *OpenUserFile(char *prompt, char *mode);

main()
{
userDB userdatebase;

userdatebase = ReadDateBase();
ProcessDateBase(userdatebase);
}


/* Section 1 -- Functions to read the date file */


/* Function: ReadDateBase
* Usage: userDB = ReadDateBase();
* -----------------------------------------
* This function read the entire datebase and the
* coded file 'message.txt'
*/

static userDB ReadDateBase(void)
{
FILE *infile;
FILE *message;
userDB result;

infile = OpenUserFile("The name of the datebase: ", "r");
message = fopen("c:\message.txt", "r");
result = (userDB)malloc(sizeof(userDB));
ReadUserInfo(infile, result);
CopyFile(result->message, message);
fclose(infile); /* test */
fclose(message); /* test */
return(result);
}

/* Function: ReadUserInfo
* Usage: ReadUserInfo();
* ----------------------------
* It is used to record the user information from the user's
* datebase.It reads the formed string from the userdatebase
* and recorded it as user's name and password. And gives the
* 'nusers' valid users number.
*/

static void ReadUserInfo(FILE *infile, userDB userdatebase)
{
userT userinfo;
int nscan;
int nusers = 0;
char *name;
char *password;
char termch;

name = (char*)malloc(MaxNameLen+1);
password = (char*)malloc(MaxPasswordLen+1);

while (TRUE) {
nusers++ ;
nscan = fscanf(infile, "%[^:]: %s%c", name, password, &termch);
if (nscan == EOF) break;
if ((nscan != 3) || (termch != '\n')) break;
userinfo = (userT)malloc(sizeof(userT));
userinfo->name = name; /*test*/
userinfo->password = password; /*test*/
userdatebase->userdate[nusers] = userinfo;
printf("%s \n", userdatebase->userdate[1]->name); /*test*/
printf("%d \n", nusers);
userdatebase->nusers = nusers;
}
}

/* Function: CopyFile
* Usage: CopyFile();
* ----------------------
* This function copies the external file content to
* a internal file
*/

static void CopyFile(FILE *outfile, FILE *infile)
{
int ch;

while ((ch = getc(infile)) != EOF) putc(ch, outfile);
}

/* Function: Decipher
* Usage: Decipher(codefile);
* -------------------------------
* This function is userd to decode the message file
* But for testing, it just put the charactor onto the screen.
* It is to be expanded.
*/

static void Decipher(FILE *message)
{
int ch;

while ((ch = getc(message)) != EOF) putc(ch, stdout);

}

/* Function: OpenUserFile
* Usage: fileptr = OpenUserFile(prompt, mode);
* -------------------------------------------------------
* This function prompts the user for a file name using the
* prompt string supplied by the user and the attempts to
* open that file with the specified mode. If the file is
* opened successfully, OpenUserFile returns the appropriate
* file pointer. If the open operation fils, the user is
* informed of the failure and given an opportunity to enter
* another file name.
*/

static FILE *OpenUserFile(char *prompt, char *mode)
{
char *filename;
FILE *result;

filename = (char*)malloc(Buffer);

while (TRUE) {
printf("%s", prompt);
scanf("%s", filename);
result = fopen(filename, mode);
if (result != NULL) break;
printf("Can't open then file \"%s\"\n", filename);
}
}

/* Section 2 -- Functions to process the datebase */


/* Function: ProcessDateBase
* Usage: ProcessDateBase();
* --------------------------------
* This function is to process the whole information.
* Firstly, it get the information from the user.
* Secondly, it compare the input user information with the
* exist user information from the datebase, if match, then
* print the coded message on the screen through the
* function 'Decipher()'.
*/

static void ProcessDateBase(userDB userdatebase)
{
userT userinfo;

userinfo = (userT)malloc(sizeof(userT));

userinfo = GetUserInfo();
printf("%s \n", userinfo->name); /*test*/
printf("%s \n", userinfo->password);
if (match(userinfo, userdatebase)) {
Decipher(userdatebase->message);
printf("pass\n");
} else {
printf("user doesn't find ! \n");
}
}

/* Function: GetUserInfo
* Usage: user = GetUserInfo();
* -----------------------------------
* This function is used to record the infomation from
* the external user information.
*/

static userT GetUserInfo(void)
{
userT userinfo;
char *name;
char *password;

name = (char*)malloc(MaxNameLen+1);
password = (char*)malloc(MaxPasswordLen+1);
userinfo = (userT)malloc(sizeof(userT));

printf("Please input username: ");
scanf("%s", name);
userinfo->name = name;
printf("Please input password: ");
scanf("%s", password);
userinfo->password = password;
return(userinfo);
}

/* Function: match
* Usage: if (...), while (...)
* -----------------------------
* This function returns a 'TRUE' boolean value when the input
* user information is match with the information from
* the user datebase .
*/

static bool match(userT userinfo, userDB userdatebase)
{
int i;
char *username;
char *userpassword;
bool flagname, flagpwd;
int n = userdatebase->nusers;

username = (char*)malloc(MaxNameLen+1);
userpassword = (char*)malloc(MaxPasswordLen+1);

username = userinfo->name;
userpassword = userinfo->password;

flagname = FALSE;
flagpwd = FALSE;

printf("%d \n",strcmp(username, userdatebase->userdate[1]->name)); /*test*/

for (i = 1; i < n; i++) {
if (strcmp(username, userdatebase->userdate[i]->name) ==0) {
printf("%d \n", i);
printf("Pass !\n");
flagname = TRUE;
break;
}
}

if (!flagname) printf("name error !\n");

if (flagname) {
for (i = 1; i < n; i++) {
if (strcmp(userpassword, userdatebase->userdate[i]->password) == 0) {
printf("Accessing ! \n");
flagpwd = TRUE;
}
} else {
printf("password error !\n");
}
}

return(flagname && flagpwd);

}

-------------------------------------------------------------------------------------------------
修改了点输入时的错误以及四楼提出的逻辑错误(谢谢),但主要问题不在这里
而是:

printf("%d \n",strcmp(username, userdatebase->userdate[1]->name)); /*test*/

即使是与库中user1的用户名相同,strcmp()的返回值也不是0,所以我判断是前
面指针赋值时出现了点问题,在指针操作部分有问题。








[此贴子已经被作者于2006-2-26 9:43:17编辑过]

搜索更多相关的解决方案: 程序设计  用户  验证  

----------------解决方案--------------------------------------------------------
/*test*/ 注释部分有些地方有问题

希望大家帮忙看看问题出在哪?我认为是指针赋值后 "match()" 时出错了, 跟踪程序时是在strcmp()时出错,但我想是更前面的指针(有些是 字符串与指针)之间赋值时的出的问题。
注:附件中有txt版本
―― 谢谢

[此贴子已经被作者于2006-2-25 23:00:27编辑过]


----------------解决方案--------------------------------------------------------
if (!(flagname && flagpwd)) {
for (i = 1; i < n; i++) {
if (strcmp(userpassword, userdatebase->userdate[i]->) == 0) {
printf("Accessing ! \n");
flagpwd = TRUE;
}
} else {
printf("password error !\n");
}
}

这里有逻辑问题
----------------解决方案--------------------------------------------------------
看三楼这部分程序,除了逻辑错误
第三行userdatebase->userdate[i]->?? 应该是userdatebase->userdate[i]->password 才对吧
if (flagname)
{
if (strcmp(userpassword, userdatebase->userdate[i]->password) == 0)
{
printf("Accessing ! \n");
flagpwd = TRUE;
}
else
printf("password error !\n");
}

还是你仔细看吧,我没仔细看你的思路,只看了这点,也许和你思路不一样呢

[此贴子已经被作者于2006-2-25 23:32:43编辑过]


----------------解决方案--------------------------------------------------------
问题未能解决,所以顶上去,大家在帮忙看看
----------------解决方案--------------------------------------------------------
  相关解决方案