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

C语言实现CS50凯撒密码算法触发Segmentation fault段错误求解

错误原因与修复方案

核心错误(触发段错误)

cipher函数中声明的string ctext = NULL;是空指针,你直接对空指针执行ctext[i]赋值操作,访问了未申请的非法内存,这是触发段错误的直接原因。你需要先为密文字符串申请足够的内存空间,大小为明文长度+1(额外1位存储字符串结束符\0)。

其他逻辑错误

  • 你把获取用户明文输入、调用加密的逻辑写在了密钥合法性校验的循环体内,会导致密钥有多少位,就会要求用户输入多少次明文,不符合需求。应该先完成所有密钥字符的合法性校验,全部为数字后再执行后续流程。
  • 加密完成后没有给密文字符串末尾添加结束符\0,输出时会出现乱码。
  • 硬编码ASCII值96、65可读性差,替换为'a'、'A'更易维护。

修复后完整代码

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

string cipher(string ptext, int k);

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    // 先校验密钥所有字符都是数字
    for (int i = 0, n = strlen(argv[1]); i < n; i++)
    {
        if (!isdigit(argv[1][i]))
        {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }
    // 校验通过后再执行后续逻辑
    int k = atoi(argv[1]) % 26; // 提前对26取模,避免k过大
    string ptext = get_string("Text:");
    string ctext = cipher(ptext, k);
    printf("Plain Text: %s \nCipher Text: %s\n", ptext, ctext);
    free(ctext); // 释放申请的内存,避免内存泄漏
    return 0;
}


string cipher(string ptext, int k)
{
    int len = strlen(ptext);
    string ctext = malloc(len + 1); // 申请内存,多留1位存\0
    for (int i = 0; i < len; i++) {
        if (islower(ptext[i]))
        {
            ctext[i] = (ptext[i] - 'a' + k) % 26 + 'a';
        }
        else if (isupper(ptext[i]))
        {
            ctext[i] = (ptext[i] - 'A' + k) % 26 + 'A';
        }
        else
        {
            ctext[i] = ptext[i];
        }
    }
    ctext[len] = '\0'; // 补字符串结束符
    return ctext;
}

验证效果

输入密钥为1,明文输入Hi!时,输出密文为Ij!,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 22:54:01