【问题标题】:Why is this my code producing a segmentation fault when there is only argc[1]?当只有 argc[1] 时,为什么我的代码会产生分段错误?
【发布时间】:2021-07-10 06:01:59
【问题描述】:

我正在参加 CS 入门课程 (CS50x),但遇到了一个小问题。

当只有argc[1] 时,为什么这段 C 代码会产生分段错误?

它应该打印语句。为什么不打印错误?

提前致谢!

int main(int argc, string argv[])
{
    //HOUSEKEEPING
    //Get/Validate Key
    string key = argv[1];
    int finalKey = atoi(key) % 26;

    while (argc != 2)
    {
        for (int i = 0; i < strlen(key); i++)

            if (!isdigit(key[i]))
            {
                printf("Usage: ./caesar key\n");
                return 1;
            }

            else
            {
                printf("Usage: ./caesar key\n");
                return 1;
            }
            //...

【问题讨论】:

  • 在访问argv[1]之前需要检查是否argc == 2
  • 此外while (argc != 2) 是无稽之谈,因为argc 不会改变。这里不需要循环
  • 请缩进你的程序。
  • 你没有通过凯撒键。对于 1 (a --> b, b-->c, ...) 的凯撒键,您可以通过 ./caesar 1 运行您的程序。
  • @i486 这是 CS50 BS。他们使用typedef char* string 让学生有点相信C 中有string 类型。

标签: c command-line-arguments cs50 argv argc


【解决方案1】:

argc 是一个整数参数,用于跟踪命令行中的参数数量,没有argc[1],如果您提供第二个命令行参数,则可能有argv[1],否则尝试读取从不存在的argv[x] 等于undefined behavior,这可能是您遇到的分段错误的罪魁祸首。

根据这些信息,您会注意到 while 语句毫无意义,argc 保持不变,因此循环要么永远不会执行,要么如果 argc 不是 2 则循环将无限(并且程序不会崩溃)。

if-else 也很可疑,它总是打印消息并返回,如果字符是数字或不是数字相似。

尽管程序的目标是,语法正确的代码应该看起来更像这样:

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

    if (argc == 2)
    {
        string key = argv[1];

        int finalKey = atoi(key) % 26; //*

        for (int i = 0; i < strlen(key); i++)
        {
            if (!isdigit(key[i]))
            {
                printf("Usage: ./caesar key\n");
                return 1;
            }
        }
    }
    else
    {
        puts("Wrong number of arguments, usage: ./caesar key\n");
    }
}

* 请注意atoi 非常不安全,请考虑使用strtol。并且可以直接在argv[1]操作int finalKey = atoi(argv[1]) % 26;

【讨论】:

    【解决方案2】:

    我想你对argcargv的操作不是很清楚。 argc 表示传递给主函数的参数个数。至少它会收到一个参数(argv[0],这将是编译后的 C 代码的名称)。此外,它将接收您通过命令行传递的所有参数。

    总之,正确的做法是:

    if (argc >=2){
            string key = argv[1];
    }
    

    否则,当您尝试访问argv[1] 值时,您将获得segmentation fault

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-08
      • 2017-12-04
      • 2015-05-10
      • 2021-02-18
      • 1970-01-01
      • 2018-05-13
      相关资源
      最近更新 更多