C编程中的Segmentation fault错误

Segmentation fault error in C programming

当我只是 运行 ./caesar 命令时,我在这个程序中遇到 分段错误 。我发现当我在代码开头写 int length=strlen(argv[1]); 时会打印错误,当我将此行放在 ( for 循环),但我不明白为什么它在那里工作正常,而不是在程序的顶部??

非常感谢您的帮助!!提前致谢。

int main(int argc,string argv[])
{
    int s=0;
    int length=strlen(argv[1]); ##GETS ERROR

    if ( argc !=2)
    {
        printf("Usage:./caesar key\n");
        return 1;
    }
    else
    {

        int length=strlen(argv[1]); ##WORKS FINE

        for (int i = 0; i < length ; i += 1)
        {
            int c= argv[1][i];
            if (isdigit(c))
            {
                s += 1;
            }
            else
            {
                s+=0;
            }
        }
        printf("%i\n",s);
        if (length==s)
        {
            int key = atoi(argv[1]);
            printf("int:%i\n",key);
        }
        else
        {
            printf("Usage:./caesar key\n");
        }
    }
}

您的第一次尝试:

int length=strlen(argv[1]); ##GETS ERROR

这会报错,因为,有一个参数,当你调用main时:没有索引为1的参数。这种方式是不安全的,所以你应该先处理参数的数量,然后,parse/read/use 参数。

第二次尝试时(处理 argc 的地方):


    if (argc !=2)
    {
        printf("Usage:./caesar key\n");
        return 1;
    }
    else
    {

    int length=strlen(argv[1]); ##WORKS FINE
    .....
    }

你已经确定了,你有两个参数。因为,如果没有,您的代码就会退出。问题是,您不使用相同的测试用例测试您的代码版本:您的新代码和新代码(有 if 和没有)将使用两个参数;但是,如果只有一个参数,旧的将失败,而第二个则不会(它将只是程序中的 return)。

很可能,您需要在争论中使用 caesar。不要只输入“./caesar”,而是输入 "caesar blah"。更重要的是,您应该编写一些代码来检查参数的数量。例如,您可以写类似

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

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s arg1 arg2 ...\n", argv[0]);
        return EXIT_FAILURE;
    }

    /*
    ...
    Fill in code
    ...
    */
}

编辑:我觉得这里发生了一些误解。如果将 "int s = strlen(argv[1]);" 放在片段 "if (argc != 2) ..." 之前,则 caesar 程序将尝试对不存在的字符串调用 strlen,从而导致段错误。本质上,在做任何其他事情之前总是先写错误检查代码("if (argc != 2) ...")。此外,在 "if (argc != 2) ..." 之后不需要 else。我觉得去掉 else 关键字并将正文保留在 else 子句中是更好的风格。