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

C语言中使用printf无法打印rotate函数返回字符的问题求助

凯撒密码实现问题排查与修复

问题描述

实现凯撒密码时,调用char rotate(char c, int n)函数后仅能打印数字而非字符,输入abc时仅显示plaintext: ,无密文输出。相关代码如下:

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


bool only_digits(string arg);
char rotate(char c, int n);

int main(int argc, string argv[])
{

   // Make sure program was run with just one command-line argument

   if (argc !=2)

    {
    printf("Usage: ./caesar key\n");
    return 1;
    };

    // Make sure every character in argv[1] is a digit
    if ( only_digits(argv[1])==0)
    {
     printf("Usage: ./caesar key\n");
     return 1;
    };

     // Convert argv[1] from a `string` to an `int`
     int key = atoi(argv[1]);

    // Prompt user for plaintext//
    string text = get_string("plaintext: \n");

    // For each character in the plaintext:

     printf("ciphertext: ");

     for (int i = 0; i < strlen(text); i++)
     {
      char ch = (rotate(text[i], key));
      
      printf("%c", ch);
     };


}

bool only_digits(string arg)
{
      // Rotate the character if it's a letter
     for (int i = 0; i < strlen(arg); i++)
     {
         if (!isdigit(arg[i]))
         {
          return false;
         }
     }
     return true;
}

char rotate(char c, int n){

     if (isupper(c))
     {
          c -=65;
          c = (c + n) % 26;
          c = c + '0';
          return c;
     }

      else if (islower(c))
     {
          c -=97;
          c = (c + n) % 26;
          c = c + '0';
          return c;

     }
      else
      return c;


}

错误分析

核心问题出在rotate函数的字符转换逻辑:

  • 处理大写字母时,偏移计算完成后,错误地使用c = c + '0'将数值转为数字字符(ASCII码48-57),而非大写字母(ASCII码65-90)。
  • 处理小写字母时同理,应该加'a'(ASCII码97)转回小写字母,而非'0'。
  • 当输入abc这类小写字母时,偏移后的数值加'0'得到的是不可打印字符或非预期字符,导致终端无正常密文显示。

修复后的代码

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

bool only_digits(string arg);
char rotate(char c, int n);

int main(int argc, string argv[])
{
    // 确保程序仅接收一个命令行参数
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // 确保命令行参数全为数字
    if (!only_digits(argv[1]))
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // 将字符串参数转为整数密钥
    int key = atoi(argv[1]);

    // 提示用户输入明文
    string text = get_string("plaintext: ");

    // 输出密文前缀
    printf("ciphertext: ");

    // 遍历明文字符并转换
    for (int i = 0; i < strlen(text); i++)
    {
        char ch = rotate(text[i], key);
        printf("%c", ch);
    }
    printf("\n"); // 增加换行,使输出格式更规范
}

bool only_digits(string arg)
{
    for (int i = 0; i < strlen(arg); i++)
    {
        if (!isdigit(arg[i]))
        {
            return false;
        }
    }
    return true;
}

char rotate(char c, int n)
{
    if (isupper(c))
    {
        c -= 'A'; // 用字符常量替代魔法数字65,可读性更强
        c = (c + n) % 26;
        c += 'A'; // 转回大写字母
        return c;
    }
    else if (islower(c))
    {
        c -= 'a'; // 用字符常量替代魔法数字97
        c = (c + n) % 26;
        c += 'a'; // 转回小写字母
        return c;
    }
    else
    {
        return c; // 非字母字符直接返回
    }
}

额外优化说明

  • 替换了魔法数字65、97为'A'、'a',提升代码可读性。
  • 移除了代码中多余的分号(如if语句块后的分号),避免潜在语法问题。
  • 在密文输出末尾增加换行符,使终端输出格式更整洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:41:47