希望提供解决方案,谢谢了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include <locale.h>
void printMenu(void);
int checkPwd(int type);
int encryptFile(char *sourcefile, char *secretKey, char *targetFile, int encryptionMethod);
char redo(void);
int main() {
char sourcefile[30], targetFile[30], secretKey[21], action;
int encryptionMethod; // 加密方式
while (1) {
system("cls"); // 清屏
printMenu();// 显示菜单
scanf("%c", &action);// 输入要执行的操作
fflush(stdin);// 清空stdin缓冲区
system("cls");
switch (action) {
// 退出系统
case 'z':
exit(0);
break;
// 文件加密
case 'a':
while (1) {
printf("输入要加密的文件名(含路径):");
scanf("%s", sourcefile);
printf("输入密钥:");//密钥是用户自己定义的,可以随意给需要加密的文件添加密钥
scanf("%s", secretKey);
printf("加密后的文件名(含路径):");//给加密后的文件命名,并保存
scanf("%s", targetFile);
printf("选择加密方式:\n");
printf("1. 异或加密\n");
printf("2. 其他加密方式\n");
printf("请选择:");
scanf("%d", &encryptionMethod);
if (encryptFile(sourcefile, secretKey, targetFile, encryptionMethod)) {
printf("文件[%s]加密成功,保存在[%s]。\n", sourcefile, targetFile);
}
if (redo() == 'a') {// 继续加密文件
system("cls");
} else {// 回到主菜单
break;
}
}
break;
case 'b':
while (1) {
printf("输入要解密的文件名(含路径):");
scanf("%s", sourcefile);
printf("输入密钥:");
scanf("%s", secretKey);
printf("解密后的文件名(含路径):");//对解密的文件系统又可以提供保存路径
scanf("%s", targetFile);
printf("选择解密方式:\n");
printf("1. 异或解密\n");
printf("3. 其他解密方式\n");
printf("请选择:");
scanf("%d", &encryptionMethod);
if (encryptFile(sourcefile, secretKey, targetFile, encryptionMethod)) {
printf("文件[%s]解密成功,保存在[%s]。\n", sourcefile, targetFile);
}
if (redo() == 'a') {// 继续解密文件
system("cls");
} else {
break;// 回到主菜单
}
}
break;
case 'c':
while(1){
struct stu
{
char name[10];
int num;
int age;
char addr[15];
}
boya[2],boyb[2],*pp,*qq;
{
FILE *fp;
char ch;
int i;
pp=boya;
qq=boyb;
if((fp=fopen("D:\ceshi.txt","wb+"))==NULL)
{
printf("Cannot open file strike any key exit!");
}
printf("\ninput data\n");
for(i=0;i<2;i++,pp++)
{
scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr);
}
pp=boya;
fwrite(pp,sizeof(struct stu),2,fp);
//将文件指针重新指向一个流的开头
rewind(fp);
fread(qq,sizeof(struct stu),2,fp);
printf("\n\nname\tnumber age addr\n");
for(i=0;i<2;i++,qq++)
{
printf("%s\t%5d%7d %s\n",qq->name,qq->num,qq->age,qq->addr);
}
fclose(fp);
}
if(redo() == 'a'){ // 重新输入信息
system("cls");
}else{ // 回到主菜单
break;
}
}
break;
default:
printf("没有相应的菜单!按任意键回到主菜单...");
getch();
}
}
return EXIT_SUCCESS;
}
/**
* 显示程序菜单
**/
void printMenu() {
printf("***************** 文本加密解密软件 *****************\n");
printf("* *\n");
printf("* *\n");
printf("* 请从下面的菜单中选择你要进行的操作: *\n");
printf("* a. 文件加密 *\n");
printf("* b. 文件解密 *\n");
printf("* c. 将信息存放到文件中 *\n");
printf("* z. 退出系统 *\n");
printf("* *\n");
printf("* *\n");
printf("****************************************************\n");
}
/**
* 加密/解密文件
*
* @param sourcefile 要加密/解密的文件名
* @param secretKey 密钥
* @param targetFile 加密/解密后要保存的文件名
*
* @return 加密成功或失败的数字表示
0:加密失败
1:加密成功
**/
int encryptFile(char *sourcefile, char *secretKey, char *targetFile, int encryptionMethod) {
FILE *fpSource, *fpTarget;// 要打开的文件的指针
char buffer[21];// 缓冲区,用于存放从文件读取的数据
int readCount,// 每次从文件中读取的字节数
keyLen = strlen(secretKey),// 密钥的长度
i; // 循环次数
// 以二进制方式读取/写入文件
fpSource = fopen(sourcefile, "rb");
if (fpSource == NULL) {
printf("文件[%s]打开失败,请检查文件路径和名称是否输入正确!\n", sourcefile);
return 0;
}
fpTarget = fopen(targetFile, "wb");
if (fpTarget == NULL) {
printf("文件[%s]创建/写入失败!请检查文件路径和名称是否输入正确!\n", fpTarget);
return 0;
}
// 不断地从文件中读取 keyLen 长度的数据,保存到buffer,直到文件结束
while ((readCount = fread(buffer, 1, keyLen, fpSource)) > 0) {
if (encryptionMethod == 1) { // 异或加密
for (i = 0; i < readCount; i++) {
buffer[i] ^= secretKey[i];
}
} else if(encryptionMethod==2){
// 位移加密
for (i = 0; i < readCount; i++) {
buffer[i] = buffer[i] + keyLen;
}
}else if(encryptionMethod==3){ // 因为位移加密和位移解密,无法共用一个处理方法,故新增一个模式来处理位移解密
// 位移解密
for (i = 0; i < readCount; i++) {
buffer[i] = buffer[i] - keyLen;
}
}
fwrite(buffer, 1, readCount, fpTarget);
}
fclose(fpSource);
fclose(fpTarget);
return 1;
}
char redo() {
char action;
printf("\n接下来你希望:\n");
printf("a. 继续当前操作\n");
printf("b. 回到主菜单\n");
// 不停的等待用户输入,直到输入正确
while (1) {
fflush(stdin);
scanf("%c", &action);
fflush(stdin);
if (action != 'a' && action != 'b') {
printf("没有相应的菜单,请重新选择。\n");
} else {
return action;
break;
}
}
}
如果是要解决写入文本文件打开后显示乱码,可以将fwrite()和fread()替换为fprintf()和fscanf()即可,因为fwrite()和fread()在Windows下是二进制文件读写函数,以文本文件的形式打开是会出现乱码的,而fprintf()和fscanf()应该大致是以文本模式来读写的。
修改如下:
参考链接:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include <locale.h>
void printMenu(void);
int checkPwd(int type);
int encryptFile(char *sourcefile, char *secretKey, char *targetFile, int encryptionMethod);
char redo(void);
int main() {
char sourcefile[30], targetFile[30], secretKey[21], action;
int encryptionMethod; // 加密方式
while (1) {
system("cls"); // 清屏
printMenu();// 显示菜单
scanf("%c", &action);// 输入要执行的操作
fflush(stdin);// 清空stdin缓冲区
system("cls");
switch (action) {
// 退出系统
case 'z':
exit(0);
break;
// 文件加密
case 'a':
while (1) {
printf("输入要加密的文件名(含路径):");
scanf("%s", sourcefile);
printf("输入密钥:");//密钥是用户自己定义的,可以随意给需要加密的文件添加密钥
scanf("%s", secretKey);
printf("加密后的文件名(含路径):");//给加密后的文件命名,并保存
scanf("%s", targetFile);
printf("选择加密方式:\n");
printf("1. 异或加密\n");
printf("2. 其他加密方式\n");
printf("请选择:");
scanf("%d", &encryptionMethod);
if (encryptFile(sourcefile, secretKey, targetFile, encryptionMethod)) {
printf("文件[%s]加密成功,保存在[%s]。\n", sourcefile, targetFile);
}
if (redo() == 'a') {// 继续加密文件
system("cls");
} else {// 回到主菜单
break;
}
}
break;
case 'b':
while (1) {
printf("输入要解密的文件名(含路径):");
scanf("%s", sourcefile);
printf("输入密钥:");
scanf("%s", secretKey);
printf("解密后的文件名(含路径):");//对解密的文件系统又可以提供保存路径
scanf("%s", targetFile);
printf("选择解密方式:\n");
printf("1. 异或解密\n");
printf("3. 其他解密方式\n");
printf("请选择:");
scanf("%d", &encryptionMethod);
if (encryptFile(sourcefile, secretKey, targetFile, encryptionMethod)) {
printf("文件[%s]解密成功,保存在[%s]。\n", sourcefile, targetFile);
}
if (redo() == 'a') {// 继续解密文件
system("cls");
} else {
break;// 回到主菜单
}
}
break;
case 'c':
while(1) {
struct stu {
char name[10];
int num;
int age;
char addr[15];
}
boya[2],boyb[2],*pp,*qq;
{
FILE *fp;
char ch;
int i;
pp=boya;
qq=boyb;
// 这里文件模式修改下
// https://blog.csdn.net/kangjianwei101/article/details/50517536
// https://blog.csdn.net/weixin_47423314/article/details/106200349
if((fp=fopen("D:\ceshi.txt","w+"))==NULL) {
printf("Cannot open file strike any key exit!");
}
printf("\ninput data\n");
for(i=0; i<2; i++,pp++) {
scanf("%s%d%d%s",boya[i].name,&boya[i].num,&boya[i].age,boya[i].addr);
// https://blog.csdn.net/shulianghan/article/details/117328308
// 使用fprintf()来格式化写入数据到文件
fprintf(fp,"%s %d %d %s\n",boya[i].name,boya[i].num,boya[i].age,boya[i].addr);
}
pp=boya;
//fwrite(pp,sizeof(struct stu),2,fp);
//将文件指针重新指向一个流的开头
rewind(fp);
// fread(boyb,sizeof(struct stu),2,fp);
printf("\n\nname\tnumber\tage\taddr\n");
for(i=0; i<2; i++,qq++) {
// 使用fscanf()从文件格式化读取数据
fscanf(fp,"%s\t%d\t%d\t%s\n",boyb[i].name,&boyb[i].num,&boyb[i].age,boyb[i].addr);
printf("%s\t%d\t%d\t%s\n",boyb[i].name,boyb[i].num,boyb[i].age,boyb[i].addr);
}
fclose(fp);
}
if(redo() == 'a') { // 重新输入信息
system("cls");
} else { // 回到主菜单
break;
}
}
break;
default:
printf("没有相应的菜单!按任意键回到主菜单...");
getch();
}
}
return EXIT_SUCCESS;
}
/**
* 显示程序菜单
**/
void printMenu() {
printf("***************** 文本加密解密软件 *****************\n");
printf("* *\n");
printf("* *\n");
printf("* 请从下面的菜单中选择你要进行的操作: *\n");
printf("* a. 文件加密 *\n");
printf("* b. 文件解密 *\n");
printf("* c. 将信息存放到文件中 *\n");
printf("* z. 退出系统 *\n");
printf("* *\n");
printf("* *\n");
printf("****************************************************\n");
}
/**
* 加密/解密文件
*
* @param sourcefile 要加密/解密的文件名
* @param secretKey 密钥
* @param targetFile 加密/解密后要保存的文件名
*
* @return 加密成功或失败的数字表示
0:加密失败
1:加密成功
**/
int encryptFile(char *sourcefile, char *secretKey, char *targetFile, int encryptionMethod) {
FILE *fpSource, *fpTarget;// 要打开的文件的指针
char buffer[21];// 缓冲区,用于存放从文件读取的数据
int readCount,// 每次从文件中读取的字节数
keyLen = strlen(secretKey),// 密钥的长度
i; // 循环次数
// 以二进制方式读取/写入文件
fpSource = fopen(sourcefile, "rb");
if (fpSource == NULL) {
printf("文件[%s]打开失败,请检查文件路径和名称是否输入正确!\n", sourcefile);
return 0;
}
fpTarget = fopen(targetFile, "wb");
if (fpTarget == NULL) {
printf("文件[%s]创建/写入失败!请检查文件路径和名称是否输入正确!\n", fpTarget);
return 0;
}
// 不断地从文件中读取 keyLen 长度的数据,保存到buffer,直到文件结束
while ((readCount = fread(buffer, 1, keyLen, fpSource)) > 0) {
if (encryptionMethod == 1) { // 异或加密
for (i = 0; i < readCount; i++) {
buffer[i] ^= secretKey[i];
}
} else if(encryptionMethod==2) {
// 位移加密
for (i = 0; i < readCount; i++) {
buffer[i] = buffer[i] + keyLen;
}
} else if(encryptionMethod==3) { // 因为位移加密和位移解密,无法共用一个处理方法,故新增一个模式来处理位移解密
// 位移解密
for (i = 0; i < readCount; i++) {
buffer[i] = buffer[i] - keyLen;
}
}
fwrite(buffer, 1, readCount, fpTarget);
}
fclose(fpSource);
fclose(fpTarget);
return 1;
}
char redo() {
char action;
printf("\n接下来你希望:\n");
printf("a. 继续当前操作\n");
printf("b. 回到主菜单\n");
// 不停的等待用户输入,直到输入正确
while (1) {
fflush(stdin);
scanf("%c", &action);
fflush(stdin);
if (action != 'a' && action != 'b') {
printf("没有相应的菜单,请重新选择。\n");
} else {
return action;
break;
}
}
}
另外,为了证实寄存器可以存放变量,我又想起了程序员透明和程序员不透明这个知识点,经过查阅发现,通用寄存器是汇编程序员不透明,这也证实了之前的汇编层调用寄存器说法的真实性