- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不断更改此代码的循环部分,但我的 check50 总是失败。我不知道发生了什么事。下面是我的代码:
#include <stdio.h>
#include <ctype.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
// declare variables
int cipherText;
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
printf("\n");
return 1;
}
// keyword is the second command line argument
string key = argv[1];
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if ((key[i] >= '0') && (key[i] <= '9'))
{
printf("Keyword must consist only of letters.");
return 1;
}
}
// get the plaintext
string plainText = GetString();
// encypher - iterate over the characters in string, print each one encrypted
for (int i = 0, j = 0, n = strlen(plainText); i < n; i++, j++)
{
// start the key again if key shorter than plainText
if (j >= strlen(key))
{
j = 0;
}
// skip key[j] if plainText[i] is not an alpha character
if (!isalpha(plainText[i]))
{
j = (j-1);
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j%keylen])%26) + 'A';
printf("%c", cipherText);
}
else if (islower(plainText[i]))
{
cipherText = (plainText[i] - 'a');
cipherText = ((cipherText + key[j%keylen])%26 + 'a');
printf("%c", cipherText);
}
else
{
printf("%c", plainText[i]);
}
}
printf("\n");
return 0;
}
有些人回答说:“第一个 for 循环有问题。条件是在应该检查 i > keylen
时检查 i < keylen
”。
此外,在计算下一个输出值时,步骤应该是
这就是我尝试做的。
最佳答案
鉴于此代码:
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if ((key[i] >= '0') && (key[i] <= '9'))
{
printf("Keyword must consist only of letters.");
return 1;
}
}
循环内的测试将数字识别为“不是字母”(这是有效的),但忽略标点符号、空格等。您可能应该使用 if (!isalpha(key[i]))
进行测试(并且有礼貌地打印错误消息中的错误字符,该字符应该打印在标准错误上,而不是标准输出,并应以换行符结尾:
fprintf(stderr, "Keyword must consist only of letters (%c found at %d)\n",
key[i], i+1);
您可以对其进行改进,使其不会尝试使用 %c
打印不可打印的字符,但这是朝着正确方向迈出的一大步。
你真的不需要在循环中设置n
;您只需在循环之前设置 keylen
即可,因此您可以编写:
for (int i = 0; i < keylen; i++)
但是,这主要是装饰性的。你真正的问题在于:
// start the key again if key shorter than plainText
if (j >= strlen(key))
{
j = 0;
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
您可以通过键在每次迭代中修改键字符串。但不幸的是,如果 key 中的任何字母是 a
或 A
,您已将其转换为 '\0'
,这意味着 strlen(key)
返回与之前不同的答案。因此,您应该使用 keylen
代替 strlen()
。 AFAICS,如果没有 a
或 A
,则该部分代码没问题。
之后,您将拥有:
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j%keylen])%26) + 'A';
printf("%c", cipherText);
}
j % keylen
是多余的; j
已限制为 0
.. keylen-1
。与小写文本的代码类似。
将这些更改放在一起,并使用 fgets()
虚拟一个 GetString()
函数,我得到:
#include <stdio.h>
#include <ctype.h>
// #include <cs50.h>
#include <stdlib.h>
#include <string.h>
typedef char *string;
static char *GetString(void)
{
static char buffer[4096];
if (fgets(buffer, sizeof(buffer), stdin) == 0)
{
fprintf(stderr, "EOF detected in GetString()\n");
exit(EXIT_SUCCESS);
}
buffer[strlen(buffer) - 1] = '\0';
return buffer;
}
int main(int argc, string argv[])
{
// declare variables
int cipherText;
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
printf("\n");
return 1;
}
// keyword is the second command line argument
string key = argv[1];
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0; i < keylen; i++)
{
if (!isalpha(key[i]))
{
printf("Keyword must consist only of letters (%c at %d)\n",
key[i], i+1);
return 1;
}
}
// get the plaintext
string plainText = GetString();
// encypher - iterate over the characters in string, print each one encrypted
for (int i = 0, j = 0, n = strlen(plainText); i < n; i++, j++)
{
// start the key again if key shorter than plainText
if (j >= keylen)
{
j = 0;
}
// skip key[j] if plainText[i] is not an alpha character
if (!isalpha(plainText[i]))
{
j = (j - 1);
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j]) % 26) + 'A';
printf("%c", cipherText);
}
else if (islower(plainText[i]))
{
cipherText = (plainText[i] - 'a');
cipherText = ((cipherText + key[j]) % 26 + 'a');
printf("%c", cipherText);
}
else
{
printf("%c", plainText[i]);
}
}
printf("\n");
return 0;
}
示例运行:
$ ./vigenere bakedalaska
What a wonderful world! The news is good, and the Vigenere cipher is solved.
Xhkx d wznvorguv arrwd! Lre oegw ls rogn, aod dlh Vtgwxese mmshpr ac splfig.
$
关于c - 为什么我的 vigenere.c 不工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26921484/
我正在查看 http://rosettacode.org/wiki/Vigen%C3%A8re_cipher#Java 上提供的 Vigene Ciphere 源代码.我尝试自己测试该程序,但它并没有
我刚刚解决了CS50中的Vigenere问题,但是仍然只有一个错误,即非字母字符,当你用纯文本编写任何没有空格、逗号、任何非字母的内容时,程序将运行良好,但是如果您写了任何非字母字符,例如空格,下一个
我在使用 Vigenere 时遇到了一些问题,需要一些帮助。 /* This program is a Vigenere Cipher. I am Daniel of Asguard. */ #inc
伙计,我以为我已经拥有了!我一直在研究 Vigenere 问题并且已经接近了,但是当我检查时不断收到此错误。当 key 必须循环回来时,看起来好像有问题。想法? 这是错误: :) vigenere.c
我编写了一个 Java 程序,该程序使用 Vigenere 密码进行编码,加密工作正常,但解密不适用于某些特殊情况。 例如,如果明文为“k”且 key 为“y”,则它会正确生成密文“i”((10 +
任务是在运行程序时给出关键字参数,我将其保存为string k,然后用户输入文本,程序将根据关键字输出输入的文本。 A = 0,B = 1,所以如果关键字是 ABABA,文本是 hello,它会输出
我原来有一个凯撒的密码,看起来是这样的: #include #include int main (int argc, char const *argv[]) { printf("I
所以我的老师创造了这个 vigenere 密码,他说它可以工作。然而,在使用在线 vigenere 密码检查其结果后,它似乎不是正确加密的结果。 我不知道如何修复它,我想知道是否有人可以指导我找出错误
我正在编写 Vigenere Cipher 作为 CS50 的一部分。这是我的代码。 #include #include #include #include #include int main(int
我正在尝试制作维吉尼亚密码。当我尝试加密消息时,出现以下错误。 cipherCharIndexValue = baseAlphabet.index(keyList[keyIncrement])
我是编程新手。这是我到目前为止编写的代码。忽略加密本身的细节;我知道这需要更多的工作。当我尝试运行该程序时,收到段错误错误消息。如果 argc != 2 我会收到消息,如果 argc == 2 它会打
我正在参加 Edx 上的在线类(class) cs50,我有一个作业,其中我必须创建一个程序,用户在其中输入关键字(然后用于加密)和需要在 Vigenere 中加密的字符串。密码。 Vigenere
我不明白为什么它不起作用。当有 3 个或更多参数时它会提示,但当只有一个 Vigenere 参数时它不会提示。我看过其他有同样问题的人,他们说这可以解决......不知道我在这里缺少什么。当我运行 .
我正在尝试执行CS50 Vigenere exercise . #include #include #include #include #include int main(int argc,
我正在制作一个解密维吉尼亚密码的程序。用户只能给出字母键。 for (int i = 0, counter = strlen(text); i < counter; i++) {
首先我没有人可以问这种问题所以请原谅我 #include #include #include #include #include int main(int argc, string argv
#include #include #include #include #include int main(int argc, string argv[]) { // two arg
我已经制作了加密和解密 Vigenere 密码的程序,但我有几个问题。 这是一个:句子的第一个字母加密不正确。 第二个:在句子后我有字母 K。我认为这是空间原因,但我不知道如何解决。 第三个问题:加密
我正在尝试编写一个读入(-e 加密,-d 解密)、一个关键字(在加密期间使用)、原始消息来自的文本文件和另一个文本的 Vigenere Cipher加密/解密消息输出到的文件,全部来自命令行参数。我对
我正在用 C 语言实现 Vigenere 密码。我的解决方案一直错误地加密纯文本。因此,我决定对我的代码进行(有点武断的)更改。更改的目的只是通过更好地定位我的变量并为它们提供更合适的名称来使代码更具
我是一名优秀的程序员,十分优秀!