在 Caesar、Pset2 上出现“分段错误”

Getting a “segmentation Fault” on Caesar, Pset2

这是我的cs50 Ceasar (pset2)代码。

我可以编译我的程序。

但是,在尝试执行它时,我遇到了段错误。此外,在使用调试器时,我没有遇到段错误,而是在显示密文之前出现了 ^D。很像这样:

明文:你好 密文:^DIFMMP

你能指出问题出在哪里吗?

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

bool is_numerical(string e);

int main(int argc, string argv [])
{
  if (argc == 2 && is_numerical(argv[1] == true))
   {
      string t = argv [1];
      int k = atoi ( t );
      string s = get_string ("plaintext: ");
      printf ("ciphertext:" );
      for (int i = 0, n = strlen(s); i < n; i++)
      {
         char c = s[i];
         if (isalpha (c))
         {
            if (isupper(c))
            {
               int x = ((int) c - 65 + k) % 26 + 65;
               printf ("%c", (char) x);
            }
            else
            {
               int x = ((int) c - 97 + k) % 26 + 97;
               printf ("%c", (char) x);
            }
         }
         else
         {
            printf ("%c", c);
         }
      }

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

bool is_numerical(string e)
{
   for (int i = 0, n = strlen(e); i < n; i++)
   {
      if (!isalnum (e))
         return false;
   }
   return true;
}

谢谢。

这似乎有很多地方不对劲。

首先,让我们承认房间里的大象-

if (argc == 2 && is_numerical(argv[1] == true))

这会检查 argc 是否等于 2 如果 is_numerical return 在参数为 argv[1] == true 时为真,当 argc 等于 2 时,argv[1] 将是 true。所以实际上,您将整数值传递给 is_numerical每次,值为 1 - 但它期望值为 char*string.

您可能打算 is_numerical(argv[1]) == true。即,将 argv[1] 传递给 is_numerical,并将 return 值与 true 进行比较。您也可以完全省略 true 部分,因为它在布尔表达式中是多余的。

if (argc == 2 && is_numerical(argv[1]))

现在,您的 is_numerical 函数中出现了致命错误。

if (!isalnum(e))

isalnum 接受类型 char 的值(实际上是 int,但是 char 无论如何都会得到提升)。您正在将 e 传递给它。猜猜 estringchar* 是什么类型。你不应该传递字符串的每个字符,所以 e[i] 在那个循环中吗?

if (!isalnum(e[i]))

您的代码中可能存在更多未立即显现的算法问题。但是 is_numerical 处的致命错误是分段错误背后的原因。

忠告,始终使用-Wall编译以在编译期间捕获这些错误。