command.h
command.cpp
file_operate_class.h
file_operate_class.cpp
register_info_class.h
register_info_class.cpp
keygen.cpp
MakeFile
// command.h
#ifndef _COMMAND_H_
#define _COMMAND_H_
#include <iostream>
#include <fstream>
#include <algorithm>
#include <io.h>
#include <direct.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <cstring>
#include <string>
#include <iomanip>
#include <cstdlib>
#include <conio.h>
const int LIM = 254; // 可输入用户名的长度
const char * const REG_FILE_NAME = "register.dat"; // 要操作的文件
using namespace std;
enum LOOP { KEEP, STOP, DUMP }; // 对循环的控制
enum MARK { WHITE, BLACK, NONE }; // 用户状态标识
enum OPERATE { ADD, BLOCK, UNBLOCK, DEL, GET }; // 用户操作标识
typedef LOOP LoopControl;
typedef MARK MarkSign;
typedef OPERATE Operate;
typedef struct RegisterInformation // 注册完整信息
{
char regName[LIM]; // 注册名
unsigned long regCode; // 生成的序列号
MarkSign regMark; // 当前注册名的使用状态
} RegInfo;
const char * GetExePath(char * exeName); // 返回程序所在目录
void View(); // 程序主界面
void EatLine(); // 消除输入时的垃圾字符
unsigned long BuildRegCode(const char * name); // 产生一个序列号
void Error(const char * errorInfo); // 异常函数
bool HaveSpace(const char * str); // 检查字符串中是否有空字符
#endif
// top
// command.cpp
#include "command.h"
/*
接收程序运行时的名称。
对这个字符串进行分析,从最后一个字符开始,遇到第一个'/'(dos)或'/'(unix)。
的时候将后面的文件名截断,前面部分即为程序所在的路径。
然后将其返回。
例:
如果
C:/>d:/dome/dome.exe
那么返回"d:/dome"
如果
$ /home/dome/dome.out
那么返回"/home/dome"
如果
C:/>dome.exe (或C:/>./dome.exe)
那么返回".",在dos中则代表当前目录
如果
$ ./dome.out
那么返回".",在unix中代表当前目录
*/
const char * GetExePath(char * exeName)
{
const char DOS_PATH_SIGN = '/';
const char UNIX_PATH_SIGN = '/';
const char STRING_END_SIGN = '{post.abstract}';
const char CUR_DIR = '.';
char * exePath = exeName;
int pathLength = (int)strlen(exePath);
for (int n = pathLength - 1; n >= 0; -- n)
if (exePath[n] == DOS_PATH_SIGN || exePath[n] == UNIX_PATH_SIGN)
{
exePath[n] = STRING_END_SIGN;
break;
}
if (pathLength == strlen(exePath))
{
exePath[0] = CUR_DIR;
exePath[1] = STRING_END_SIGN;
}
return exePath;
}
// 程序的界面
// Pre:
// Post: 显示程序的主界面
void View()
{
cout << "/n/n/n/t/t/t/t== KeyGen ==/n/n"
<< "/t/t______________________________________________/n/n/n"
<< "/t/t/t1. 注册一个新用户/n"
<< "/t/t/t2. 查询用户信息/n"
<< "/t/t/t3. 删除一个用户/n"
<< "/t/t/t4. 将用户加入黑名单/n"
<< "/t/t/t5. 解禁用户/n"
<< "/t/t/t6. 显示所有用户信息/n"
<< "/t/t/t7. 退出/n/n"
<< "/t/t______________________________________________/n"
<< "/n/t/t请选择..." << flush;
}
// 生成一个序列号
// Pre: 接收一个字符串
// Post: 根据字符串,通过相应的算法生成一个长整型数字,
// 即序列号。并返回这个数字(序列号)。
unsigned long BuildRegCode(const char * name)
{
typedef unsigned long ULINT;
const ULINT IF_ONLY_SEVEN_BIT = 9999999;
const char STRING_END_SIGN = '{post.abstract}';
int n = 0, ch = 0;
ULINT code = 0;
for (; (ch = name[n]) != STRING_END_SIGN; ++ n)
code += (ch * ch + n);
code *= 190;
if (code <= IF_ONLY_SEVEN_BIT)
code = code * 10 + 5;
return code;
}
// 异常
// Pre: 接收字符串
// Post: 根据传入参数执行的异常处理。
void Error(const char * errorInfo)
{
cerr << errorInfo;
exit(EXIT_FAILURE);
}
// 检查字符串中是否有空字符
// Pre: 接收字符串
// Post: 如果有空字符返回true,反之返回false
bool HaveSpace(const char * str)
{
int i = 0;
for (; str[i] != '{post.abstract}'; ++ i)
if (str[i] == ' ' ||
str [i] == '/t')
return true;
return false;
}
// top
// file_operate_class.h
#include "command.h"
#ifndef FILE_OPERATE_CLASS_H_
#define FILE_OPERATE_CLASS_H_
extern const char * const REG_FILE_NAME;
class FileOperate
{
private:
char * fileName;
fstream file;
public:
explicit FileOperate(const char * fn = REG_FILE_NAME);
virtual ~FileOperate() = 0;
void AddUser(const RegInfo *);
void BlockUser(const RegInfo *);
void UnblockUser(const RegInfo *);
void DeleteUser(const RegInfo *);
virtual void ShowAllUser() = 0;
void GetUser(RegInfo *);
protected:
int InFile(const RegInfo *);
};
#endif
// top
// file_operate_class.cpp
#include "file_operate_class.h"
FileOperate::FileOperate(const char * fn)
{
fileName = new char [strlen(fn) + 1];
strcpy(fileName, fn);
}
FileOperate::~FileOperate()
{
delete [] fileName;
}
// 查找文件中是否有相应记录,如果有则返回所在的序号,没有则返回 -1
int FileOperate::InFile(const RegInfo * reg)
{
int rec = -1;
RegInfo r;
file.open(fileName, ios_base::in | ios_base::binary);
if (!file.is_open())
Error("文件打开失败");
else
{
int n = 0;
file.seekg(0);
while (file.read((char *) &r, sizeof r))
{
if (!strcmp(r.regName, reg->regName))
rec = n;
++ n;
}
if (file.eof())
{
file.clear();
file.close();
}
else
Error("文件读取失败");
}
return rec;
}
// 在文件中加入一条新记录,如果记录已存在,则根据记录的标识
// 显示已注册过或者是已在黑名单中
void FileOperate::AddUser(const RegInfo * reg)
{
int rec = InFile(reg);
if (rec == -1)
{
file.open(fileName,
ios_base::out | ios_base::app | ios_base::binary);
file.write((char *) reg, sizeof *reg);
if (file.fail())
Error("文件写入失败");
file.clear();
file.close();
cout << reg->regName << " 注册成功/n";
cout << "/n用户名: " << reg->regName
<< "/n序列号: " << reg->regCode << endl;
}
else
{
RegInfo regTmp;
streampos place = rec * sizeof *reg;
file.open(fileName, ios_base::in | ios_base::binary);
file.seekg(place);
file.read((char *) ®Tmp, sizeof regTmp);
file.clear();
file.close();
if (regTmp.regMark == WHITE)
cout << "已被注册的用户名/n";
else if (regTmp.regMark == BLACK)
cout << "已被列入黑名单/n";
}
}
// 将已有用户加入黑名单,如果用户不存在则显示相应信息
// 如果已经存在,且标识为BLACK,那么显示已在黑名单
// 否则加入黑名单
void FileOperate::BlockUser(const RegInfo * reg)
{
int rec = InFile(reg);
if (rec == -1)
{
RegInfo block = *reg;
block.regMark = BLACK;
file.open(fileName,
ios_base::out | ios_base::app | ios_base::binary);
file.write((char *) &block, sizeof block);
if (file.fail())
Error("文件写入失败");
file.clear();
file.close();
cout << reg->regName << " 已被加入黑名单/n";
}
else
{
RegInfo regTmp;
streampos place = rec * sizeof *reg;
file.open(fileName,
ios_base::in | ios_base::out | ios_base::binary);
file.seekg(place);
file.read((char *) ®Tmp, sizeof regTmp);
if (regTmp.regMark == BLACK)
{
file.clear();
file.close();
cout << regTmp.regName << " 已经在黑名单中/n";
}
else if (regTmp.regMark == WHITE)
{
regTmp.regMark = BLACK;
file.clear();
file.seekp(place);
file.write((char *) ®Tmp, sizeof regTmp);
if (file.fail())
Error("文件写入失败");
file.clear();
file.close();
cout << regTmp.regName << " 已被加入黑名单/n";
}
}
}
// 将已有用户加入白名单,如果用户不存在则显示相应信息
// 如果已经存在,且标识为WHITE,那么显示已在白名单
// 否则加入白名单
void FileOperate::UnblockUser(const RegInfo * reg)
{
int rec = InFile(reg);
if (rec == -1)
cout << "没有找到相应的记录/n";
else
{
RegInfo regTmp;
streampos place = rec * sizeof *reg;
file.open(fileName,
ios_base::in | ios_base::out | ios_base::binary);
file.seekg(place);
file.read((char *) ®Tmp, sizeof regTmp);
if (regTmp.regMark == WHITE)
{
file.clear();
file.close();
cout << regTmp.regName << " 不在黑名单中/n";
}
else if (regTmp.regMark == BLACK)
{
regTmp.regMark = WHITE;
file.clear();
file.seekp(place);
file.write((char *) ®Tmp, sizeof regTmp);
if (file.fail())
Error("文件写入失败");
file.clear();
file.close();
cout << regTmp.regName << " 已被解封/n";
}
}
}
// 删除一个用户记录,如果用户不存在则显示相应信息
void FileOperate::DeleteUser(const RegInfo * reg)
{
int rec = InFile(reg);
if (rec == -1)
cout << "没有找到相应的记录/n";
else
{
int len = 10;
int setp = 1;
RegInfo * tmp = new RegInfo [len + 1], p1;
file.open(fileName,
ios_base::in | ios_base::binary);
file.seekg(0);
int i = 0;
while (file.read((char *) &p1, sizeof p1))
{
if (i < len)
tmp[i] = p1;
else
{
int lentmp = len;
RegInfo * tmp2 = new RegInfo [lentmp + 1];
copy(&tmp[0], &tmp[len], &tmp2[0]);
len += setp;
delete [] tmp;
tmp = tmp2;
tmp[i] = p1;
}
++ i;
}
len = i;
if (file.eof())
file.clear();
file.close();
creat(fileName, _S_IWRITE);
file.open(fileName,
ios_base::out | ios_base::binary);
file.seekg(0);
i = 0;
while (i < len)
{
if (i != rec)
file.write((char *) &tmp[i], sizeof tmp[i]);
++ i;
}
if (!file.good())
{
delete [] tmp;
Error("文件写入失败");
}
file.clear();
file.close();
delete [] tmp;
cout << reg->regName << " 删除成功/n";
}
}
// 显示记录文件中的所有记录
void FileOperate::ShowAllUser()
{
int rc = 1;
RegInfo reg;
file.open(fileName,
ios_base::in | ios_base::binary);
file.seekg(0);
cout << left;
cout << setw(6) << "编号" << setw(25) << "用户名"
<< setw(10) << " 序列号" << setw(5) << "用户状态" << endl;
cout << "_________________________________________________/n/n";
while (file.read((char *) ®, sizeof reg))
{
cout << setw(4) << rc ++ << " " << setw(25) << reg.regName
<< setw(12) << reg.regCode;
if (reg.regMark == WHITE)
cout << setw(5) << "正常/n";
else if (reg.regMark == BLACK)
cout << setw(5) << "禁用/n";
}
cout << "_________________________________________________/n/n";
if (file.eof())
file.clear();
file.close();
}
// 显示一个用户的所有信息,如果用户不存在,显示相应的信息
void FileOperate::GetUser(RegInfo * reg)
{
int rec = InFile(reg);
if (rec == -1)
cout << "没有找到相应的记录/n";
else
{
streampos place = rec * sizeof *reg;
file.open(fileName,
ios_base::in | ios_base::binary);
file.seekg(place);
file.read((char *) reg, sizeof *reg);
file.clear();
file.close();
cout << left;
cout << endl;
cout << setw(25) << "用户名" << setw(12) << " 序列号"
<< setw(5) << "用户状态" << endl;
cout << "_____________________________________________/n/n";
cout << setw(25) << reg->regName
<< setw(12) << reg->regCode;
if (reg->regMark == WHITE)
cout << setw(5) << " 正常/n";
else if (reg->regMark == BLACK)
cout << setw(5) << " 禁用/n";
}
}
// top
// register_info_class.h
#include "file_operate_class.h"
#ifndef REGISTER_INFO_CLASS_H_
#define REGISTER_INFO_CLASS_H_
class RegisterInfo : virtual private FileOperate
{
private:
RegInfo users;
public:
RegisterInfo() : FileOperate() {}
~RegisterInfo() {}
void OperateUser(const char *, Operate);
void ShowAllUser();
};
#endif
// top
// register_info_class.cpp
#include "register_info_class.h"
extern const int LIM;
void RegisterInfo::OperateUser(const char * n, Operate oper)
{
char name[LIM];
strncpy(name, n, LIM);
strupr(name);
strcpy(users.regName, name);
users.regCode = BuildRegCode(users.regName);
users.regMark = WHITE;
switch (oper)
{
case ADD:
FileOperate::AddUser(&users);
break;
case BLOCK:
FileOperate::BlockUser(&users);
break;
case UNBLOCK:
FileOperate::UnblockUser(&users);
break;
case GET:
FileOperate::GetUser(&users);
break;
case DEL:
FileOperate::DeleteUser(&users);
break;
default:
break;
}
}
void RegisterInfo::ShowAllUser()
{
FileOperate::ShowAllUser();
}
// top
// keygen.cpp
#include "command.h"
#include "register_info_class.h"
extern const char * const REG_FILE_NAME;
extern const int LIM;
int main(int argc, char *argv[])
{
system("TITLE KeyGen");
RegisterInfo user;
LoopControl loop;
char name[LIM];
const char *exePath = GetExePath(argv[0]);
chdir(exePath);
// 判断文件是否存在,如果不存在创建一个新文件
fstream file(REG_FILE_NAME, ios_base::in);
if (!file.is_open())
{
file.close();
creat(REG_FILE_NAME, _S_IWRITE);
}
else
file.close();
chmod(REG_FILE_NAME, _S_IWRITE);
while (1)
{
system("CLS");
View();
switch (getche())
{
case '1':
system("CLS");
cout << "输入你要注册的用户名, 直接回车返回: ";
cin.getline(name, LIM);
while (name[0] != '{post.abstract}')
{
if (HaveSpace(name))
cout << "/n名称中不能包含空格/n/n";
else
user.OperateUser(name, ADD);
cout << "/n输入你要注册的用户名, 直接回车返回: ";
cin.getline(name, LIM);
}
loop = KEEP;
break;
case '2':
system("CLS");
cout << "输入你要查询的用户名, 直接回车返回: ";
cin.getline(name, LIM);
while (name[0] != '{post.abstract}')
{
user.OperateUser(name, GET);
cout << "/n输入你要查询的用户名, 直接回车返回: ";
cin.getline(name, LIM);
}
loop = KEEP;
break;
case '3':
system("CLS");
cout << "输入你要删除的用户名, 直接回车返回: ";
cin.getline(name, LIM);
while (name[0] != '{post.abstract}')
{
user.OperateUser(name, DEL);
cout << "/n输入你要删除的用户名, 直接回车返回: ";
cin.getline(name, LIM);
}
loop = KEEP;
break;
case '4':
system("CLS");
cout << "输入你要列入黑名单的用户名, 直接回车返回: ";
cin.getline(name, LIM);
while (name[0] != '{post.abstract}')
{
if (HaveSpace(name))
cout << "/n名称中不能包含空格/n/n";
else
user.OperateUser(name, BLOCK);
cout << "/n输入你要列入黑名单的用户名, 直接回车返回: ";
cin.getline(name, LIM);
}
loop = KEEP;
break;
case '5':
system("CLS");
cout << "输入你要解封的用户名, 直接回车返回: ";
cin.getline(name, LIM);
while (name[0] != '{post.abstract}')
{
user.OperateUser(name, UNBLOCK);
cout << "/n输入你要解封的用户名, 直接回车返回: ";
cin.getline(name, LIM);
}
loop = KEEP;
break;
case '6':
system("CLS");
user.ShowAllUser();
cout << "请按任意键继续. . .";
getch();
loop = KEEP;
break;
case '7':
loop = STOP;
break;
default:
loop = DUMP;
break;
}
if (loop == DUMP)
continue;
else if (loop == STOP)
break;
}
chmod(REG_FILE_NAME, _S_IREAD);
system("CLS");
return EXIT_SUCCESS;
}
// top
# Project: keygen
# Makefile created by Melody
CPP = d:/dev-cpp/bin/g++.exe
CC = d:/dev-cpp/bin/gcc.exe
OBJ = ./obj/command.o ./obj/file_operate_class.o ./obj/register_info_class.o ./obj/keygen.o
LINKOBJ = ./obj/command.o ./obj/file_operate_class.o ./obj/register_info_class.o ./obj/keygen.o
LIBS = -L"D:/dev-cpp/lib"
INCS = -I"D:/dev-cpp/include"
CXXINCS = -I"D:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"D:/Dev-Cpp/include/c++/3.4.2/backward" -I"D:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"D:/Dev-Cpp/include/c++/3.4.2" -I"D:/Dev-Cpp/include"
BIN = ./exe/keygen.exe
CXXFLAGS = $(CXXINCS) -O3
CFLAGS = $(INCS) -O3
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before keygen.exe all-after
clean: clean-custom
$(RM) $(BIN) $(OBJ)
keygen.exe: $(OBJ)
$(CPP) $(LINKOBJ) -o "./exe/keygen.exe" $(LIBS)
./obj/command.o: command.cpp command.h
$(CPP) -c command.cpp -o ./obj/command.o $(CXXFLAGS)
./obj/file_operate_class.o: file_operate_class.cpp command.h file_operate_class.h
$(CPP) -c file_operate_class.cpp -o ./obj/file_operate_class.o $(CXXFLAGS)
./obj/register_info_class.o: register_info_class.cpp command.h register_info_class.h file_operate_class.h
$(CPP) -c register_info_class.cpp -o ./obj/register_info_class.o $(CXXFLAGS)
./obj/keygen.o: keygen.cpp command.h register_info_class.h
$(CPP) -c keygen.cpp -o ./obj/keygen.o $(CXXFLAGS)
// top