首页 > 解决方案 > c 中的分割错误,第 2 周凯撒,cs50x 哈佛课程

问题描述

所以我在哈佛cs50在线课程(2021x版)的第2周。我们应该编写一个加密文本的程序,将每个字母的 ASCII 码移动一定的量,由用户通过命令行决定。这是完整的问题。我快完成了,但是当我尝试运行程序时(它编译得很好),它告诉我有一个分段错误。我真的不明白这个问题。我读过这个问题与访问无法访问的某个内存部分有关?我该如何解决这个问题?先感谢您!这是我的代码..

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

int main(int argc, string argv[])
{
    int k, i;
    if (argc == 2 && isdigit(argv[1]) && argv[1] > 0)
    {
        k = (int) argv[1];
        string plaintext = get_string("plaintext: ");
        printf("cyphertext: ");
        for (i = 0; i < strlen(plaintext); i++)
        {
            if (islower(plaintext[i]) || isupper(plaintext[i]))
            {
                printf("%c", (((plaintext[i] + k) - 97) % 26) + 97);
                return 0;
            }
            
        }
    }
    else
    {
        printf("Usage: ./caesar key");
        return 1;
    }
}

标签: csegmentation-faultcs50caesar-cipher

解决方案


我在哈佛 cs50 在线课程的第 2 周

我很遗憾听到这个消息。您的大多数问题都源于糟糕的 CS-50 类,它诱使您相信 C 以某种方式具有预制的糖衣字符串类。它没有,它只有以空终止结尾的原始字符数组,因此大多数字符串操作都是手动的。

其他问题来自在向您指出错误时不听编译器。这里有几个:

  • isdigit(argv[1])没有意义。一个好的编译器会告诉你很多,例如clang:

    警告:从'string'(又名'char *')转换为更小的整数类型'int'

    您比较一个指向字符串的指针,而isdigit需要一个字符。为了使用isdigit,您必须在循环中为字符串的每个字符调用它。

  • argv[1] > 0没有意义,因为它将指针与 0 进行比较。

    错误:指针和零之间的有序比较

  • k = (int) argv[1];也没有意义。

    警告:从'string'(又名'char *')转换为更小的整数类型'int'

    要将字符串转换为整数,必须使用strtol函数,例如k = strtol(argv[1], NULL, 10). 它带有您可能也想使用的各种错误处理。

    而且因为k包含废话-实际上它包含转换为整数的内存地址,所以plaintext[i] + k也变得废话。

  • if (islower(plaintext[i]) || isupper(plaintext[i]))没有意义,它说“如果一个字符是小写还是大写”。嗯,大概是吧?相反,您可能打算使用touppertolower执行所有计算,无论用户键入什么内容,都以大写或小写形式进行。


推荐阅读