You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CS50替换密码程序修改else分支后失效的原因咨询

替换密码程序的逻辑错误分析

问题描述

我正在编写一个替换密码程序,采用CS50的语法规范。当代码保留else分支时,程序运行完全正常;但如果将else分支替换为仅匹配'!'、'.'、','、空格的else if分支后,程序只会复制原输入字符串。请问这是什么原因?

原代码片段

#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;
}

修改后的分支代码

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

原因分析

1. 循环顺序完全错误

你的代码当前是先遍历26个字母(i循环),再遍历输入字符串的每个字符(j循环),这会导致逻辑彻底混乱:

  • 对于任意一个字母字符,比如H,只有当i循环到对应索引(i=7)时,会被替换成密码字符;但后续的i循环(从8到25)会通过else分支把这个字符重新覆盖为原字符。
  • 最终只有最后一个字母(Z/z)的字符会保留替换结果,其他字母都会被改回原字符——你所谓的“原代码运行正常”其实是错觉,它根本没有正确执行替换。

正确的循环顺序应该是先遍历输入字符串的每个字符(j循环),再遍历26个字母找匹配(i循环),这样每个字符只会被处理一次:

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];
            break; // 找到匹配后跳出循环,避免无效遍历
        }
        else if (word[j] == alphabet_lower[i])
        {
            letter_switch[j] = key_lower[i];
            break;
        }
    }
}

2. 修改分支后的逻辑漏洞

当你把else换成仅匹配标点/空格的else if后,结合错误的循环顺序,会出现以下问题:

  • 对于字母字符,当i不是对应字母时,既不满足if/else if的匹配条件,也不属于标点/空格,因此letter_switch[j]不会被赋值。
  • 后续的i循环中,只有当i恰好对应该字母时才会替换,但之后的i循环又不会再修改它——但因为原循环顺序的问题,大部分字母会被后续循环的无操作保留为初始的随机值,而你看到的原字符串,其实是之前错误循环中else分支覆盖的结果残留。

内容的提问来源于stack exchange,提问作者Kalle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:17:07