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

C语言加密程序循环提前终止及Segmentation fault问题求助

解决替换密码程序中的段错误与循环问题

核心问题分析

  • 空数组越界访问:你定义的int cypher[] = {}是长度为0的空数组,尝试给cypher[i]赋值时会访问未分配的内存区域,这是触发段错误的直接原因。C语言中空数组没有预留存储空间,写入操作属于非法内存访问。
  • 错误的循环条件:转换大小写的循环使用i < plain[i]作为终止条件完全不符合逻辑——plain[i]是字符的ASCII值(比如'H'对应72),这会导致循环要么提前终止,要么遍历远超字符串长度的范围,破坏内存。
  • 缺失参数合法性检查:程序未验证用户是否传入密钥参数(即argc == 2),如果直接运行程序不输入密钥,argv[1]为NULL,调用strlen(argv[1])会直接崩溃。
  • 大小写处理逻辑混淆:注释标注要将key转为大写,但实际代码修改的是plain字符串,且直接修改原字符串可能引发问题,同时丢失了原字符的大小写信息。

修正后的代码

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

int main(int argc, string argv[])
{
    // 检查是否传入密钥参数,且密钥长度为26
    if (argc != 2 || strlen(argv[1]) != 26)
    {
        printf("Usage: ./substitution key\n");
        printf("Key must contain 26 characters.\n");
        return 1;
    }

    string key = argv[1];
    // 验证密钥是否全为字母
    for (int i = 0; i < 26; i++)
    {
        if (!isalpha(key[i]))
        {
            printf("Key must contain only alphabetic characters.\n");
            return 1;
        }
        // 将密钥统一转为大写,方便后续处理
        key[i] = toupper(key[i]);
    }

    // 获取明文
    string plain = get_string("plaintext: ");
    // 为密文分配内存,长度为明文长度+1(存储结束符'\0')
    char *cypher = malloc(strlen(plain) + 1);
    if (cypher == NULL)
    {
        printf("Memory allocation failed.\n");
        return 1;
    }

    // 加密逻辑
    for (int i = 0; i < strlen(plain); i++)
    {
        char c = plain[i];
        if (isupper(c))
        {
            // 大写字母:计算索引(A=0),从密钥取对应字符,保持大写
            int idx = c - 'A';
            cypher[i] = key[idx];
        }
        else if (islower(c))
        {
            // 小写字母:计算索引,从密钥取对应字符后转小写
            int idx = c - 'a';
            cypher[i] = tolower(key[idx]);
        }
        else
        {
            // 非字母字符直接保留
            cypher[i] = c;
        }
    }
    // 添加字符串结束符
    cypher[strlen(plain)] = '\0';

    // 输出密文
    printf("cyphertext: %s\n", cypher);
    // 释放分配的内存
    free(cypher);

    return 0;
}

关键修正说明

  1. 内存分配:使用malloc为密文分配足够内存,长度为明文长度加1(用于存储字符串结束符'\0'),避免越界访问;使用完后用free释放内存,防止内存泄漏。
  2. 正确的循环条件:遍历字符串时使用i < strlen(plain),确保遍历每个字符直到字符串结束。
  3. 完善的参数检查:先验证argc == 2,再检查密钥长度,同时验证密钥是否全为字母,提升程序健壮性。
  4. 保留大小写信息:加密时根据原字符的大小写,将密钥中的对应字符转换为相同大小写,符合常规加密需求。
  5. 处理非字母字符:直接保留明文里的非字母字符(如空格、标点),提升程序实用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:50:45