如何用C语言实现读取文件、凯撒加解密后写入另一文件?
凯撒密码C语言实现问题修复
需求说明
凯撒密码(Caesar Cipher)是最早、最简单的加密技术之一,属于替换密码的一种,即给定文本中的每个字母都被字母表中向下偏移固定位数的字母替换。例如偏移量为1时,A替换为B,B替换为C,以此类推。该方法据传以尤利乌斯·凯撒命名,他曾使用该方式与官员通信。
要对给定文本加密,需要一个称为偏移量的整数值,代表文本中每个字母向下移动的位数。
加密可以用模运算表示:首先将字母转换为数字,规则为A = 0, B = 1,…, Z = 25,偏移量为n的字母加密可用如下数学公式描述:E_n(x)=(x+n)mod 26 (Encryption Phase with shift n) D_n(x)=(x-n)mod 26 (Decryption Phase with shift n)请编写算法并用C语言实现程序,从名为"test.txt"的文件中读取数据,按照上述规则转换后,保存到名为"final.txt"的另一个文件中。
原有代码核心问题
- 非法字符串赋值:
data[50] = buffer;写法错误,C语言不能直接把字符数组指针赋值给char类型变量,且访问data[50]属于数组越界(data数组长度为50,合法下标为0~49),应该用strcpy完成字符串拷贝。 - 缓冲区溢出风险:buffer定义长度为30,
fgets读取时指定长度为50,会超出buffer内存范围导致栈溢出。 - 无文件异常处理:调用
fopen打开test.txt后没有判断返回值,文件不存在或无读取权限时会直接崩溃。 - 偏移逻辑缺陷:如果偏移量key大于26,现有计算逻辑会得到错误结果,需要先对key取26的模再计算偏移。
- 未完成核心需求:代码仅打印加密/解密结果,没有实现将转换后内容写入final.txt的要求。
- 文件读取不完整:仅调用一次
fgets只能读取文件第一行内容,多行文本文档会丢失数据。 - 全局变量滥用:count、temp等变量无需定义为全局变量,改为局部变量逻辑更严谨。
修复后完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define BUF_SIZE 1024 char data[BUF_SIZE]; int key; // 写入结果到final.txt void write_to_file() { FILE *fp = fopen("final.txt", "w"); if (fp == NULL) { printf("无法打开final.txt写入文件\n"); return; } fputs(data, fp); fclose(fp); printf("结果已保存到final.txt\n"); } void getmessage() { FILE *file_pointer = fopen("test.txt", "r"); if (file_pointer == NULL) { printf("无法打开test.txt文件,请检查文件是否存在\n"); exit(1); } printf("----读取test.txt内容----\n"); int idx = 0; char c; // 循环读取整个文件内容 while ((c = fgetc(file_pointer)) != EOF && idx < BUF_SIZE - 1) { data[idx++] = c; } data[idx] = '\0'; printf("%s\n", data); fclose(file_pointer); } void key_input() { printf("请输入偏移量key:\t"); scanf("%d", &key); // 对key取模,兼容大于26的偏移量 key = key % 26; if (key < 0) key += 26; } void caesar_cipher_encryption() { char temp; for (int count = 0; data[count] != '\0'; count++) { temp = data[count]; if (islower(temp)) { temp = 'a' + (temp - 'a' + key) % 26; data[count] = temp; } else if (isupper(temp)) { temp = 'A' + (temp - 'A' + key) % 26; data[count] = temp; } // 非字母字符保持不变 } printf("\n加密后内容:\t%s\n", data); write_to_file(); } void caesar_cipher_decryption() { char temp; for (int count = 0; data[count] != '\0'; count++) { temp = data[count]; if (islower(temp)) { temp = 'a' + (temp - 'a' - key + 26) % 26; data[count] = temp; } else if (isupper(temp)) { temp = 'A' + (temp - 'A' - key + 26) % 26; data[count] = temp; } // 非字母字符保持不变 } printf("\n解密后内容:\t%s\n", data); write_to_file(); } int main() { int choice; getmessage(); key_input(); while (1) { printf("\n1. 加密\n2. 解密\n3. 退出\n"); printf("\n请输入你的选择:\t"); scanf("%d", &choice); switch (choice) { case 1: caesar_cipher_encryption(); break; case 2: caesar_cipher_decryption(); break; case 3: exit(0); default: printf("\n请输入正确的选项\n"); } } return 0; }
内容的提问来源于stack exchange,提问作者Majadul Haque
相关产品推荐
相关产品推荐

