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

CS50 习题集2代码运行触发Segmentation fault (core dumped)求助

凯撒密码代码段错误分析与修复

问题描述

编写的凯撒密码代码编译无报错,但运行时触发Segmentation fault (core dumped),原代码如下:

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

int main(int argc, string argv[])
{
    int k=atoi(argv[1]);
    if (argc!=2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    else if (argv[1]<0)
    {
        printf("Usage: ./caesar key\n");
        return 2;
    }
    else if (argv[1]== NULL)
    {
        printf("Usage: ./caesar key\n");
        return 3;
    }
    string plaintext= get_string("plaintext: ");
    printf("ciphertext: ");
    for(int i=0; i<strlen(plaintext); i++)
    {
            if(plaintext[i]>='a' && plaintext[i]<='z')
            {
                printf("%c", ((plaintext[i]-97+k)%26)+97);

            }
            else if(plaintext[i]>='A' && plaintext[i]<='Z')
            {
                printf("%c", ((plaintext[i]-65+k)%26)+65);
            }
    }
    printf("\n");
}

错误点分析

  • 参数访问顺序错误:代码一开始就执行int k=atoi(argv[1]);,但此时还没校验argc是否等于2。如果用户运行程序时没有传入参数(即argc=1),argv[1]是不存在的野指针,访问它直接触发段错误。
  • 无效的负数判断:argv[1]<0是把字符串指针和整数0比较,判断的是指针地址是否小于0,完全不是判断密钥数值是否为负,逻辑错误。
  • 多余的空指针判断:当argc==2时,argv[1]必然指向传入的参数字符串,不可能为NULL,这个判断毫无意义。
  • 非字母字符未处理:循环只处理大小写字母,空格、数字、符号等字符会被直接忽略,导致输出缺失内容(虽不触发段错误,但功能不完整)。

修正后的代码

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> // 用于isalpha、islower、isupper函数,让判断更清晰

int main(int argc, string argv[])
{
    // 先校验参数数量
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // 转换密钥并校验是否为正整数
    int k = atoi(argv[1]);
    if (k <= 0)
    {
        printf("Usage: ./caesar key\n");
        return 2;
    }

    string plaintext = get_string("plaintext: ");
    printf("ciphertext: ");

    for (int i = 0; i < strlen(plaintext); i++)
    {
        char c = plaintext[i];
        if (islower(c))
        {
            printf("%c", ((c - 'a' + k) % 26) + 'a');
        }
        else if (isupper(c))
        {
            printf("%c", ((c - 'A' + k) % 26) + 'A');
        }
        else
        {
            // 非字母字符直接输出
            printf("%c", c);
        }
    }
    printf("\n");

    return 0;
}

修正说明

  1. 调整参数校验顺序:先判断argc是否为2,再访问argv[1]转换密钥,避免野指针访问。
  2. 用转换后的k判断是否为正整数,替代无效的指针地址比较。
  3. 移除多余的argv[1]==NULL判断。
  4. 使用ctype.h中的islower、isupper函数简化字符类型判断,同时处理非字母字符,保证输出完整。
  5. 用字符常量'a'、'A'替代ASCII码值97、65,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:50:25