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

CS50 Pset2 Caesar:only_digits函数无法处理非数字密钥问题

修复CS50 Caesar作业中only_digits函数的问题

问题现象

完成CS50 Pset2 Caesar作业时,将only_digits的检查逻辑直接写在main函数里,能正常处理包含非数字的密钥;但调用only_digits函数时,执行./caesar 2x会出现程序超时退出的情况,且作业要求必须使用该函数。

错误分析

原only_digits函数存在三个关键问题:

  1. 返回值类型不匹配:函数声明为bool类型,但最后返回argv(指针数组),遇到非数字时返回1(int类型),触发未定义行为导致逻辑混乱。
  2. 职责越界:函数内部直接打印错误信息并返回1,但函数的核心职责应该仅为检查字符串是否全为数字,错误处理和程序终止逻辑应交给main函数。
  3. 效率低下:循环中每次调用strlen(argv[1]),strlen会重复遍历字符串计算长度,增加不必要开销,是超时问题的诱因之一。

修复方案

  1. 调整函数参数:仅传入需要检查的目标字符串(即argv[1]),无需传递整个argv数组。
  2. 优化长度计算:提前计算字符串长度并存储,避免循环内重复调用strlen。
  3. 修正返回逻辑:函数仅返回bool值——遇到非数字字符返回false,全部为数字则返回true,错误提示和程序终止逻辑移至main函数。
  4. 修正isdigit判断:isdigit返回非零值表示是数字,应改为!isdigit(c)来判断非数字字符。

修复后的完整代码

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

bool only_digits(string s);

int main(int argc, string argv[])
{
    if (argc == 2)
    {
        // 调用only_digits检查密钥是否全为数字
        if (!only_digits(argv[1]))
        {
            printf("Usage: ./caesar key\n");
            return 1;
        }

        // 将字符串密钥转换为整数
        int k = atoi(argv[1]);
        // 获取明文
        string plaintext = get_string("plaintext:  ");
        printf("ciphertext: ");

        // 凯撒加密逻辑
        for (int i = 0, n = strlen(plaintext); i < n; i++)
        {
            if (plaintext[i] >= 'a' && plaintext[i] <= 'z')
            {
                printf("%c", (((plaintext[i] - 'a') + k) % 26) + 'a');
            }
            else if (plaintext[i] >= 'A' && plaintext[i] <= 'Z')
            {
                printf("%c", (((plaintext[i] - 'A') + k) % 26) + 'A');
            }
            else
            {
                printf("%c", plaintext[i]);
            }
        }
        printf("\n");
        return 0;

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

bool only_digits(string s)
{
    int len = strlen(s);
    for (int i = 0; i < len; i++)
    {
        // 判断当前字符是否不是数字
        if (!isdigit(s[i]))
        {
            return false;
        }
    }
    return true;
}

修复说明

  • only_digits函数现在专注于检查字符串是否全为数字,逻辑清晰且高效。
  • main函数根据only_digits的返回值处理错误,符合单一职责原则。
  • 提前计算字符串长度避免了重复调用strlen的性能损耗,解决了超时问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:40:29