首页 > 解决方案 > 在 Caesar,Pset2 上遇到“分段错误”

问题描述

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

我能够编译我的程序。

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

明文:HELLO 密文:^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;
}

谢谢你。

标签: cs50caesar-cipher

解决方案


这似乎有很多不妥之处。

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

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

这将检查是否argc等于 2 如果参数为,is_numerical返回 true ,当等于 2 时。所以实际上,您每次都将一个整数值传递给 1 - 但它需要一个值or 。argv[1] == trueargv[1] trueargcis_numericalchar*string

你可能打算这样做is_numerical(argv[1]) == true。即,传递argv[1]is_numerical并将返回值与true. 您也可以完全省略 true 部分,因为这在布尔表达式中是多余的。

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

现在,你的is_numerical函数中有一个致命的错误。

if (!isalnum(e))

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

if (!isalnum(e[i]))

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

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


推荐阅读