----------------------
稍微有点长
用户验证程序
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编辑过]