優化C++製作的簡易密碼管理工具

最近空閒時間較多,特地複習下C++的基礎知識。

原文地址 適合練手的密碼本項目

修改(優化)點:

  1. 修復從文件中讀取數據、把數據重新寫入文件等BUG使軟件能正常運行
  2. 刪除持久化數據的多餘空格
  3. 修改每次新增都持久化爲先緩存再手動持久化
  4. 原作只管加密不管解密
  5. 下一步基於Qt圖形化

操作截圖如下:

代碼如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#define fopen_s(pFile,filename,mode) ((*(pFile))=fopen((filename),  (mode)))==NULL

using namespace std;

/* global variables */
int lnChrLmt=20;
int lnsLmt=10;
int gCnt = 0;
char websiteArr[10][20];
char usernameArr[10][20];
char passwordArr[10][20];
char remarkArr[10][20];

char filePath[20] = "data.txt";
char spw[20] = "abcd";
int retryCnt = 3;

void init();
void readAll();
void search();
void append();
void save();
void remove();
void edit();
void startPwd();
void show();
void dump();

// remove a element from array
int remove_from_array(char a[10][20], int n, int &len) {
	if(a == NULL || n<0 || len < 0 || n>=len) {
		return -1;
	}
	int i;
	for(i = n; i < len-1; i ++) {
		memcpy(static_cast<char*>(a[i]), static_cast<char*>(a[i+1]), lnChrLmt);
	}
	--len;
	return 0;
}

// initailize program
void init() {
	FILE *pFile;
	if(fopen_s(&pFile, filePath, "r")!=0) {
		printf("error open when init");
		system("pause");
		exit(1);
	}
	int c;
	do {
		c=fgetc(pFile);
		if (c=='\n') {
			gCnt++;
		}
	} while(c!=EOF);
	fseek(pFile, 0, SEEK_SET);
	for(int i=0; i<gCnt; i++) {
		fread(websiteArr[i], lnChrLmt, 1, pFile);
		fread(usernameArr[i], lnChrLmt, 1, pFile);
		fread(passwordArr[i], lnChrLmt, 1, pFile);
		fread(remarkArr[i], lnChrLmt, 1, pFile);
		fscanf(pFile, "\n");
	}
	fclose(pFile);
}

// valid password
void startPwd() {
	char tmpStr[lnChrLmt];
	bool nSucceed = false;
	printf("input password:\n");
	scanf("%s", tmpStr);
	for(int i=retryCnt; i>=0; i--) {
		if(strcmp(spw, tmpStr)==0) {
			nSucceed = true;
			break;
		} else {
			printf(retryCnt+" times left");
		}
	}
	if(!nSucceed) {
		printf("error password");
	} else {
		printf("press any key to continue...\n");
	}
	system("pause");
}

// read data from cache
void readAll() {
	for(int i=0; i<gCnt; i++) {
		printf("No.%d record\n", i+1);
		printf("website: %s, username: %s, password: %s, remark: %s\n", websiteArr[i], usernameArr[i], passwordArr[i], remarkArr[i]);
	}
}

// search by name
void search() {
	char tmpStr[lnChrLmt];
	int targetIndex=-1;
	printf("input website to find: ");
	scanf("%s", tmpStr);
	for(int i=0; i<gCnt; i++) {
		if(strcmp(websiteArr[i], tmpStr)==0) {
			printf("website: %s, username: %s, password: %s, remark: %s\n", websiteArr[i], usernameArr[i], passwordArr[i], remarkArr[i]);
			break;
		}
	}
}

// save record to cache
void save() {
	FILE *pFile;
	if(fopen_s(&pFile, filePath, "w")!=0) {
		printf("error open write");
	}
	fwrite(websiteArr[gCnt], lnChrLmt, 1, pFile);
	fwrite(usernameArr[gCnt], lnChrLmt, 1, pFile);
	fwrite(passwordArr[gCnt], lnChrLmt, 1, pFile);
	fwrite(remarkArr[gCnt], lnChrLmt, 1, pFile);
	fprintf(pFile, "\n");
	fclose(pFile);
}

// accept record to append
void append() {
	char tmpStr[20];
	printf("input new website: ");
	scanf("%s", websiteArr[gCnt]);
	printf("username:");
	scanf("%s", usernameArr[gCnt]);
	printf("password:");
	scanf("%s", passwordArr[gCnt]);
	printf("remark:");
	scanf("%s", remarkArr[gCnt]);
	save();
	gCnt++;
	printf("append success\n");
}

// dump cached data to file
void dump() {
	FILE *pFile;
	if(fopen_s(&pFile, filePath, "w")!=0) {
		printf("error open write");
		exit(1);
	}
	fseek(pFile, 0, SEEK_SET);
	for(int i=0; i<gCnt; i++) {
		fwrite(websiteArr[i], lnChrLmt, 1, pFile);
		fwrite(usernameArr[i], lnChrLmt, 1, pFile);
		fwrite(passwordArr[i], lnChrLmt, 1, pFile);
		fwrite(remarkArr[i], lnChrLmt, 1, pFile);
		fprintf(pFile, "\n");
	}
	fclose(pFile);
	printf("dump success\n");
}

// remove one record from cache
void remove() {
	char tmpStr[lnChrLmt];
	int targetIndex=-1;
	printf("input website to remove: ");
	scanf("%s", tmpStr);
	for(int i=0; i<gCnt; i++) {
		if(strcmp(websiteArr[i], tmpStr)==0) {
			targetIndex=i;
		}
		if(targetIndex>=0) {
			remove_from_array(websiteArr, i, lnsLmt);
			remove_from_array(usernameArr, i, lnsLmt);
			remove_from_array(passwordArr, i, lnsLmt);
			remove_from_array(remarkArr, i, lnsLmt);
			printf("lnChrLmt: %d\n",lnChrLmt);
			gCnt--;
			break;
		}
	}
	printf("remove success\n");
}

// edit one record in cache
void edit() {
	char tmpStr[lnChrLmt];
	int targetIndex=-1;
	printf("input website to edit: ");
	scanf("%s", tmpStr);
	for(int i=0; i<gCnt; i++) {
		if(strcmp(websiteArr[i], tmpStr)==0) {
			printf("input website: ");
			scanf("%s",tmpStr);
			strcpy(websiteArr[i], tmpStr);
			printf("input username: ");
			scanf("%s",tmpStr);
			strcpy(usernameArr[i], tmpStr);
			printf("input password: ");
			scanf("%s",tmpStr);
			strcpy(passwordArr[i], tmpStr);
			printf("input remark: ");
			scanf("%s",tmpStr);
			strcpy(remarkArr[i], tmpStr);
			break;
		}
	}
	printf("edit success\n");
}

// prompt control information of program
void show() {
	int choiceNum = 1;
	while(choiceNum) {
		printf("Welcome to Security Book!\nChoice your operation bellow:\n");
		printf("1.Read 2.Append 3.Delete 4.Edit 5.Search 6.Dump 7.Exit\n");
		scanf("%d", &choiceNum);
		switch(choiceNum) {
			case 1: {
				readAll();
			}
			break;
			case 2: {
				append();
			}
			break;
			case 3: {
				remove();
			}
			break;
			case 4: {
				edit();
			}
			break;
			case 5: {
				search();
			}
			break;
			case 6: {
				dump();
			}
			break;
			case 7: {
				choiceNum = 0;
			}
			break;
		}
	}
	printf("bye\n");
}

// entrance
int main(int argc, char** argv) {
	init();
	startPwd();
	show();
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章