分段错误(核心已转储)- 简单

Segmentation fault (Core dumped) - simple

我是 C 的初学者。我有一个简单的程序,我想将每个关键字更改为相应的数字。例如 A = 0,B = 1 和 F = 5 等。在这种情况下关键字 "hello" 将是“7 4 11 11 14”。 我可以编译此代码,但每当我 运行 时,我都会收到错误 "Segmentation fault (core dumped)"。我尝试了几件事来改变它,但无济于事。有人可以检查我的代码并给我反馈吗?也欢迎对我的风格、逻辑和其他代码相关的东西提出建设性的反馈!

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

int main(int argc, string argv[])
{

int keylength = strlen(argv[1]);
char *key = argv[1];

// insert keyword
if (argc != 2)
{
    printf("Less commands please.");
    return 1;
}
else
{
    if (!isalpha(argv[1]))
    {
        printf("Please no numbers or weird symbols");
    }    
    else    
    {
        for (int i = 0; i < keylength; i++)
        {
            if(isupper(key[i]))
            {
                key[i] = key[i] - 65;
            }

            else if(islower(key[i]))
            {
                key[i] = key[i] - 97;
            }
        } 
    }               
}

} 

isalpha 接受字符作为输入,而不是指向字符(或字符串,如您所做的)的指针。您需要遍历字符串并单独检查每个字符。我不确定这是否会导致段错误...

另一个可能的问题:当您 运行 程序时,您是否 运行 给它添加了一个参数?

如果不存在,则 int keylength = strlen(argv[1]); 将导致段错误,因为 argv[1] 不存在。在检查参数数量后,你真的应该把它放在 else 子句中。

你可以这样做

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

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        printf("Must provide one argument\n");
        return 1;
    }

    int keylength = strlen(argv[1]);
    int i = 0;

    for( ; i <keylength; i++)
    {
        if (!isalpha(argv[1][i]))
        {
            printf("not alpha\n");
            return 1;
        }
    }

    char *key = argv[1];
    printf("b4 %s\n", argv[1]); 

    for (int i = 0; i < keylength; i++)
    {
        if(isupper(key[i]))         
            key[i] = key[i] - 65;
        else if(islower(key[i]))    
            key[i] = key[i] - 97;
    } 

    printf("after %s\n", argv[1]);
}

注意事项

  1. 在您知道 argc 至少为 2 之前不要尝试访问 argv[1]
  2. 您需要在循环中对照 isalpha 检查 argv[1] 中的每个字符。不只是将字符串指针直接传递给 isalpha.
  3. 另请注意,您正在直接更改命令行参数内存。虽然有可能这样做,但这是一种可疑的做法。最好复制 argv[1] 并更改它。我没有在我的例子中实现这个。