else 语句逻辑是古怪的

Else statement logic is wacko

提问人:Kalle 提问时间:10/4/2023 最后编辑:Vlad from MoscowKalle 更新时间:10/6/2023 访问量:114

问:

#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,所以这可能会改变一些变量定义等。

c if 语句 字符 嵌套循环 CS50

评论

3赞 Lundin 10/4/2023
string是什么,一个 ?typedefchar*
2赞 Lundin 10/4/2023
一个明显的错误是,您既没有为 null 终止分配空间,也没有向最终字符串添加空间。
2赞 Lundin 10/4/2023
另外,您的意思是“如果定义 else 语句,一切正常”?因为那样它确实只是复制了原件。
0赞 Fe2O3 10/4/2023
这是哪个版本?这似乎是一个可行的解决方案。请澄清您不明白的地方。
0赞 Kalle 10/4/2023
很抱歉没有包含更多细节。我现在更改了问题和代码,因此可能更容易理解我的问题。原始代码不起作用。但是使用 else if 语句可以修复它。

答:

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语句接受字母(我将其作为代码的修复程序)仍然有效......