【问题标题】:Segmentation fault error in C programmingC编程中的分段错误错误
【发布时间】:2020-05-13 21:07:22
【问题描述】:

当我刚刚运行 ./caesar 命令时,我在此程序中收到 Segmentation fault 错误。我发现当我在代码的开头写 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");
        }
    }
}

【问题讨论】:

  • 您用来运行它的命令行是什么? argv[1] 至少需要一个命令行参数,因此在argc 检查确保它存在之前,您不应访问它。
  • int length=strlen(argv[1]); ##GETS ERROR 因为你没有将任何参数传递给程序,第二个strlen 在你传递一个参数时工作正常,否则它不会被调用。请注意,您不需要第二个分支 (else),因为您来自 if 子句的 return 1

标签: c cs50


【解决方案1】:

你的第一次尝试:

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

这会报错,因为当你调用 main 时,有一个参数:没有索引为 1 的参数。这种方式是不安全的,所以你应该先处理参数的数量,然后再解析/读取/使用论据。

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


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

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

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

【讨论】:

  • 不,不是 C++ std::string。 CS50 string,我认为只是char*的typedef。
【解决方案2】:

很可能,您需要在参数上使用凯撒。不要只输入“./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]);”在 sn-p "if (argc != 2) ..." 之前,caesar 程序将尝试在不存在的字符串上调用 strlen,从而导致 seg 错误。本质上,总是先写错误检查代码(“if (argc != 2) ...”),然后再做其他事情。此外,“if (argc != 2) ...”之后不需要 else。我觉得摆脱 else 关键字并将正文保留在 else 子句中会更好。

【讨论】:

  • 仔细看。 检查argc 和OP 代码中的使用消息。不幸的是,argv[1] 的问题参考出现在该检查之前
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-09
  • 2011-05-07
  • 1970-01-01
相关资源
最近更新 更多