- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我为凯撒的密码写了一个密码,这个密码有效,除了我不能密码超过8个字母,我也不能处理空格。它显示“>>”这个符号而不是空格。另外,我想在代码的第二个函数中进行二进制搜索,但我不知道我是否做过。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char caesar (char x, char alphabets[]);
int j;
int main()
{
char* plain_text = malloc (10 * sizeof(char) + 1);
int key, num;
char* cipher_text = malloc (10 * sizeof(char) + 1);
printf("Plain text: ");
gets(plain_text);
printf("\nThe plain text is: ");
puts(plain_text);
printf("\nKey: ");
scanf("%d", &key);
num = (int)key;
if (key != num)
{
return 1;
}
int i;
char alphabets[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for (i=0;i<=strlen(plain_text);i++)
{
char x = plain_text[i];
caesar(x, alphabets);
cipher_text[i] = alphabets[j+key];
printf("%c", cipher_text[i]);
}
free(plain_text);
}
char caesar (char x, char alphabets[])
{
if(x == alphabets[13])
{
return 13;
}
for(j = 1; j <= 13; j++)
{
if(x == alphabets[j])
{
return j;
}
}
for(j = 13; j <= strlen (alphabets); j++)
{
if(x == alphabets[j])
{
return j;
}
}
}
最佳答案
caesar()
似乎只是以一种非常复杂的方式返回数组中字符b到z的位置,而完全忽略了a!此外,因为alphabets
不是以空结尾的字符串strlen()
在任何情况下都不是有效的操作。“加密”是由alphabets[j+key]
中的main()
完成的(不正确),使得caesar()
的命名特别糟糕,因为这根本不是它所做的。
以下函数将返回alphabet
中任何字符的密码,并保留任何其他字符不变:
char caesar( char x, int key )
{
const char alphabet[] = {'a','b','c','d','e','f','g','h',
'i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x',
'y','z'};
char cipher = x ;
for( int i = 0;
cipher == x && i < sizeof( alphabet );
i++ )
{
if( alphabet[i] == x )
{
cipher = alphabet[(i + key) % sizeof( alphabet )] ;
}
}
return cipher ;
}
key
传递到
ceasar()
比传递常量
alphabet
更有意义,并且在
alphabet
是“已知”的地方执行加密。正如您所做的那样,在
caesar()
和
main()
之间分割密码步骤是一个糟糕的设计,缺乏内聚性,并且具有不必要的耦合。
x
出现在
alphabet
中,它将被
alphabet[(i + key) % sizeof( alphabet )] ;
修改。这就添加了原来的
key
,但也添加了“环绕”(模运算),因此例如,对于
%
,
key = 1
环绕到
z
,而不是像代码一样引用
a
数组末尾以外的一个字节。关键的是,如果它没有出现在
alphabet
中,它是未修改的-这就是为什么
alphabet
是用
cipher
初始化的。当
x
被修改时(
cipher
),或者当
cipher != x
结束时,循环退出。
alphabet
的迭代中:
for (i = 0; i <= strlen(plain_text); i++ )
{
cipher_text[i] = caesar( plain_text[i], key ) ;
}
plain_text
是不寻常的,但是这里它确保了nul终结符被复制到
<= strlen()
-它不会被
cipher_text
修改。
#include <stdio.h>
#include <string.h>
char caesar( char x, int key ) ;
#define MAX_TEXT 128
int main()
{
char plain_text[MAX_TEXT] = "" ;
char cipher_text[MAX_TEXT] = "" ;
printf( "Plain text: " );
fgets( plain_text, MAX_TEXT, stdin ) ;
printf( "\nThe plain text is: %s\n", plain_text ) ;
printf( "Key: " ) ;
int key = 0 ;
scanf( "%d", &key );
for( size_t i = 0; i <= strlen( plain_text ); i++ )
{
cipher_text[i] = caesar( plain_text[i], key ) ;
}
printf( "\nThe cipher text is: %s\n", cipher_text ) ;
return 0 ;
}
Plain text: abc, xyz
The plain text is: abc, xyz
Key: 1
The cipher text is: bcd, yza
#include <ctype.h>
char caesar( char x, int key )
{
const char alphabet[] = {'a','b','c','d','e','f','g','h',
'i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x',
'y','z'};
char cipher = x ;
for( int i = 0;
cipher == x && i < sizeof( alphabet );
i++ )
{
if( alphabet[i] == tolower( x ) )
{
cipher = alphabet[(i + key) % sizeof( alphabet )] ;
if( isupper( x ) )
{
cipher = toupper( cipher ) ;
}
}
}
return cipher ;
}
caesar()
是大写,则应用
alphabet[i] == tolower( x )
生成大写密码。
Plain text: aBc, XyZ 123
The plain text is: aBc, XyZ 123
Key: 1
The cipher text is: bCd, YzA 123
cipher = toupper( cipher )
,而是在循环中分配
x
之后可以
cipher = x
-减少测试的数量-但是
arguably breaks structured programming“规则”-我不会批评其他人使用它,但这不是我的偏好。在这种情况下,您还可以使用
break
来完全跳过循环,但它具有针对重音字符的实现定义的行为,例如,如果您要扩展支持的“字母表”,它可能无法按预期工作。
char caesar( char x, int key )
{
char cipher = tolower( x ) ;
if( isalpha( x ) )
{
cipher = ((cipher - 'a') + key) % ('z' - 'a' + 1) + 'a' ;
if( isupper( x ) )
{
cipher = toupper( cipher ) ;
}
}
return cipher ;
}
cipher
阵列解决方案仍然有效。我指出这一点仅仅是因为,否则有人会对它发表评论,好像它真的是一个问题。
isalpha(x)
:
alphabet
-减去“a”的代码,得到字符
cipher = ((cipher - 'a') + key) % ('z' - 'a' + 1) + 'a'
到
(cipher - 'a')
的值0到25。
a
-添加“shift”键
z
-这个常量表达式在实际中解析为“环绕”。
... + key
a
... % ('z' - 'a' + 1)
a
% 26
z`。
关于c - 想做凯撒的密码,但不能更改最后两个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57655966/
我刚刚开始学习 C 语言类(class),并且遇到了命令行参数的问题。分配是这样的(还有更多,但这是开头有关命令行参数的部分): - 你的程序必须接受一个命令行参数,一个非负整数。 - 如果您的程序在
我需要检查命令行参数中是否有非数字字符。例如: ./problem 20x 应该打印出“不是数字”,因为它包含一个 x。我的代码似乎没有循环遍历命令行参数中的所有字符。 我基本上尝试了不同类型的循环,
这里我有从标准输入将字符流输入到数组中的代码。然后将该数组转换为二维数组。然后,它将该数组从行列顺序更改为列行顺序。然后它打印出创建凯撒移位加密的新数组。我遇到的问题是我的数组开始使用第二个用户输入的
我有点被这个问题困住了。当我运行程序时,由于某种原因,循环经过 z 的所有字母都不会打印。问题来自这个链接:http://docs.cs50.net/2016/x/ap/problems/caesar
我是一名优秀的程序员,十分优秀!