C语言 Else语句逻辑是古怪的

ldioqlga  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(69)
#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部分换成:

else if (word[j] == '!' || word[j] == '.' || word[j] == 
                     ',' || word[j] == ' ')
            {
                letter_switch[j] = word[j];
            }

否则,它只是复制原来的单词...为什么?为什么?
我正在做cs50,所以这可能会改变一些变量定义等。

bpzcxfmw

bpzcxfmw1#

问题不在于else,而在于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];
        }
    }
}
qnyhuwrf

qnyhuwrf2#

在内部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语句在循环的每次迭代中执行。
因此,在外部循环的每次迭代中,如果word[j]不等于当前字符alphabet_upper[i]alphabet_lower[i],则else部分

else 
{
    letter_switch[j] = word[j];
}

得到控制权。只有在'z''Z'在外部for循环的最后一次迭代中被转换时,字母才能被正确转换。
函数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, ! ..

相关问题