提问人:Kalle 提问时间:10/4/2023 最后编辑:Vlad from MoscowKalle 更新时间:10/6/2023 访问量:114
else 语句逻辑是古怪的
Else statement logic is wacko
问:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string key_upper = "YTNSHKVEFXRBAUQZCLWDMIPGJO";
string key_lower = "ytnshkvefxrbauqzclwdmipgjo";
string alphabet_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string alphabet_lower = "abcdefghijklmnopqrstuvwxyz";
string word = "Hello daniel, ! ..";
char letter_switch[strlen(word)];
for (int i = 0; i < 26; i++)
{
for (int j = 0; j < strlen(word); j++)
{
if (word[j] == alphabet_upper[i])
{
letter_switch[j] = key_upper[i];
}
else if (alphabet_lower[i] == word[j])
{
letter_switch[j] = key_lower[i];
}
else
{
letter_switch[j] = word[j];
}
}
}
for (int k = 0; k < strlen(word); k++)
{
printf("%c", letter_switch[k]);
}
printf("\n");
return 0;
}
我正在制作一个 chiper 程序。如果定义了 else 语句,则一切正常。所以,如果我用以下方式切换其他部分:
else if (word[j] == '!' || word[j] == '.' || word[j] ==
',' || word[j] == ' ')
{
letter_switch[j] = word[j];
}
否则它只是复制了原来的单词...... 为什么?
我正在做 cs50,所以这可能会改变一些变量定义等。
答:
3赞
th33lf
10/4/2023
#1
问题不在于其他问题,而在于 for() 循环的顺序。 您需要先遍历单词中的每个字母,然后找到它是哪个字母并从查找表中替换。如果它不是字母表,则必须按原样复制。有很多方法可以做到这一点,但是由于您似乎正在学习,因此我将向您展示一种对您的实现进行最少更改的方法,它将是这样的:
for (int j = 0; j < strlen(word); j++)
{
letter_switch[j] = word[j];
for (int i = 0; i < 26; i++)
{
if (word[j] == alphabet_upper[i])
{
letter_switch[j] = key_upper[i];
}
else if (alphabet_lower[i] == word[j])
{
letter_switch[j] = key_lower[i];
}
}
}
评论
0赞
Serge Ballesta
10/4/2023
而且你应该在成功命中后跳出循环......
0赞
Kalle
10/4/2023
我稍微更改了我的条目。如果我使用“else if”它有效(所以该结构不受 for 循环顺序的影响?),但是当使用 else 语句时,它的 for() 循环顺序?谢谢你的回答!
0赞
th33lf
10/5/2023
@SergeBallesta确实,添加该优化是件好事。
0赞
th33lf
10/5/2023
@Kalle不能确定,直到你告诉我们里面装了什么。当然,就像我提到的,有很多方法可以解决这个问题,包括不改变 for() 循环的顺序。else if
0赞
Kalle
10/6/2023
@th33lf我确实添加了其他 if 里面的内容。这让我很困惑,为什么 else 语句不起作用,并且把 else if 起作用。
0赞
Vlad from Moscow
10/4/2023
#2
在内部 for 循环中
for (int j = 0; j < strlen(word); j++)
{
if (word[j] == alphabet_upper[i])
{
letter_switch[j] = key_upper[i];
}
else if (alphabet_lower[i] == word[j])
{
letter_switch[j] = key_lower[i];
}
else
{
letter_switch[j] = word[j];
}
}
if 语句在循环的每次迭代中执行。
因此,在外循环的每次迭代中,if 不等于当前字符或 else 部分word[j]
alphabet_upper[i]
alphabet_lower[i]
else
{
letter_switch[j] = word[j];
}
获取控制权。可以正确转换字母的唯一情况是在外部 for 循环的最后一次迭代中转换字母或转换字母时。'z'
'Z'
此外,函子被称为冗余次数。strlen
您可以通过使用标准 C 函数来简化任务。strchr
例如
const size_t N = strlen( word );
char letter_switch[N];
for ( char *current = word, *target = letter_switch; *current != '\0'; ++current, ++target )
{
char *p;
if ( ( p = strchr( alphabet_upper, *current ) ) != NULL )
{
*target = key_upper[p - alphabet_upper];
}
else if ( ( p = strchr( alphabet_lower, *current ) ) != NULL )
{
*target = key_lower[p - alphabet_lower];
}
else
{
*target = *current;
}
}
for ( size_t i = 0; i < N; i++ )
{
putchar( letter_switch[i] );
}
putchar( '\n' );
这是一个演示程序。
#include <stdio.h>
#include <string.h>
typedef char *string;
int main( void )
{
string key_upper = "YTNSHKVEFXRBAUQZCLWDMIPGJO";
string key_lower = "ytnshkvefxrbauqzclwdmipgjo";
string alphabet_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string alphabet_lower = "abcdefghijklmnopqrstuvwxyz";
string word = "Hello daniel, ! ..";
const size_t N = strlen( word );
char letter_switch[N];
for (string current = word, target = letter_switch; *current != '\0'; ++current, ++target)
{
char *p;
if (( p = strchr( alphabet_upper, *current ) ) != NULL)
{
*target = key_upper[p - alphabet_upper];
}
else if (( p = strchr( alphabet_lower, *current ) ) != NULL)
{
*target = key_lower[p - alphabet_lower];
}
else
{
*target = *current;
}
}
for (size_t i = 0; i < N; i++)
{
putchar( letter_switch[i] );
}
putchar( '\n' );
}
程序输出为
Ehbbq syufhb, ! ..
评论
0赞
Kalle
10/6/2023
哇,超级精致!谢谢!得到了一些技巧来制作更好的循环。我知道我的代码效率低下,但我仍然非常困惑为什么为所有其他字符添加else if语句接受字母(我将其作为代码的修复程序)仍然有效......
评论
string
是什么,一个 ?typedef
char*