最近空閒時間較多,特地複習下C++的基礎知識。
原文地址 適合練手的密碼本項目
修改(優化)點:
- 修復從文件中讀取數據、把數據重新寫入文件等BUG使軟件能正常運行
- 刪除持久化數據的多餘空格
- 修改每次新增都持久化爲先緩存再手動持久化
- 原作只管加密不管解密
- 下一步基於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;
}