- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试用 C++ 编写凯撒密码程序。我使用了四个函数,一个用于选择 shift key ,两个用于加密和解密,最后一个用于实现凯撒密码,使用输入文件读取文本并将加密或解密的文本输出到输出文件中。我正在尝试运行代码,但它正在崩溃。我认为问题出在凯撒函数内部的某个地方。但我不知道到底是什么。有任何想法吗?这是我的代码:
#include <iostream>
#include <fstream>
using namespace std;
int chooseKey()
{
int key_number;
cout << "Give a number from 1-26: ";
cin >> key_number;
while(key_number<1 || key_number>26)
{
cout << "Your number have to be from 1-26.Retry: ";
cin >> key_number;
}
return key_number;
}
void encryption(char *w, char *e, int key){
char *ptemp = w;
while(*ptemp){
if(isalpha(*ptemp)){
if(*ptemp>='a'&&*ptemp<='z')
{
*ptemp-='a';
*ptemp+=key;
*ptemp%=26;
*ptemp+='A';
}
}
ptemp++;
}
w=e;
}
void decryption (char *e, char *w, int key){
char *ptemp = e;
while(*ptemp){
if(isalpha(*ptemp))
{
if(*ptemp>='A'&&*ptemp<='Z')
{
*ptemp-='A';
*ptemp+=26-key;
*ptemp%=26;
*ptemp+='a';
}
}
ptemp++;
}
e=w;
}
void Caesar (char *inputFile, char *outputFile, int key, int mode)
{
ifstream input;
ofstream output;
char buf, buf1;
input.open(inputFile);
output.open(outputFile);
buf=input.get();
while(!input.eof())
{
if(mode == 1){
encryption(&buf, &buf1, key);
}else{
decryption(&buf1, &buf, key);
}
output << buf;
buf=input.get();
}
input.close();
output.close();
}
int main(){
int key, mode;
key = chooseKey();
cout << "1 or 0: ";
cin >> mode;
Caesar("test.txt","coded.txt",key,mode);
system("pause");
}
这是我的程序的一些细节。我的代码模板在我的帖子的顶部。
参数w是开头的文本,par e是解密后的文本。如果我们在 w* 文本中添加 shift 键并得到 *e,则正在进行加密。反向程序生成解密函数,我有加密文本 (*e),我想获取解密文本 (*w),减去我从 chooseKey 函数中获取的 key 移位。在 Caesar 函数中,我使用了一个包含一些数据的输入文件,我想在输出文件中提取加密或解密的文本。我已经实现了加密和解密函数,我的问题是如何在凯撒函数中使用它们。我没有得到任何理想的结果,我的程序正在崩溃。请指出我的错误。有什么解决办法吗?
最佳答案
你将单个字符的地址传递给解密
buf=input.get();
// ...
encryption(&buf, &buf1, key);
然后您将其视为指向一个以空字符结尾的字符串。
while(*ptemp){
// ...
ptemp++;
}
这不会很好地工作,因为 ptemp
一开始就没有指向以 null 结尾的字符串。当您执行 ptemp++
时,您就处于未定义行为领域。
除此之外还有许多其他陷阱(例如,不要在 .eof()
上循环)和潜在的改进。
编辑哦,还有作业
w = e;
和
e = w;
没有任何效果(您将指针值分配给局部函数参数;返回时,这些变量甚至不再存在)。
这是一个清理过的镜头,我期望做你想做的事: Live on coliru
#include <iostream>
#include <fstream>
using namespace std;
int chooseKey() {
cout << "Give a number from 1-26: ";
int key_number;
while((!(cin >> key_number)) || (key_number < 1 || key_number > 26)) {
cout << "Your number have to be from 1-26 (" << key_number << "). Retry: ";
cin.clear();
}
return key_number-1;
}
template <typename InIt, typename OutIt>
void encryption(InIt f, InIt l, OutIt out, int key) {
for (InIt ptemp = f; ptemp != l; ++ptemp)
{
if(isalpha(*ptemp))
{
char base = islower(*ptemp)? 'a' : 'A';
*out++ = base + (*ptemp - base + key) % 26;
} else
*out++ = *ptemp;
}
}
void Caesar(const char *inputFile, const char *outputFile, int key, int mode) {
ifstream input(inputFile);
ofstream output(outputFile);
istreambuf_iterator<char> init(input), end;
ostreambuf_iterator<char> outit(output);
encryption(init, end, outit, mode? key : 26-key);
}
int main() {
int key, mode;
key = chooseKey();
cout << "1 or 0: ";
cin >> mode;
Caesar("test.cpp", "coded.txt", key, mode);
}
关于c++ - C++中的凯撒密码程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19646977/
我刚刚开始学习 C 语言类(class),并且遇到了命令行参数的问题。分配是这样的(还有更多,但这是开头有关命令行参数的部分): - 你的程序必须接受一个命令行参数,一个非负整数。 - 如果您的程序在
我需要检查命令行参数中是否有非数字字符。例如: ./problem 20x 应该打印出“不是数字”,因为它包含一个 x。我的代码似乎没有循环遍历命令行参数中的所有字符。 我基本上尝试了不同类型的循环,
这里我有从标准输入将字符流输入到数组中的代码。然后将该数组转换为二维数组。然后,它将该数组从行列顺序更改为列行顺序。然后它打印出创建凯撒移位加密的新数组。我遇到的问题是我的数组开始使用第二个用户输入的
我有点被这个问题困住了。当我运行程序时,由于某种原因,循环经过 z 的所有字母都不会打印。问题来自这个链接:http://docs.cs50.net/2016/x/ap/problems/caesar
我是一名优秀的程序员,十分优秀!