更改数组中的变量时出现分段错误

Segmentation error when altering a variable in an array

我正在尝试开发一个密码程序,根据他们可以自定义的 26 个字符的字符串来更改某人的文本输入。我决定走的路线是从另一个字母表字符串中减去输入字符串中的各个 char 值。然后,数值结果将存储在一个单独的 int 数组中,该数组将应用于他们想要加密的所有未来输入。为了让自己更轻松,我将 26 个字符的用户输入大写,但是当我的代码在我使用的示例用户输入中达到 'j' 时(我没有为测试目的大写的唯一字母) 我收到一个分段错误。

代码可以在下面找到。如果我的描述不够充分,我深表歉意。我对编码还是很陌生,所以会尽我所能回答任何问题。

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


int main(void)
{

    string x = "QWERTYUIOPASDFGHJKLZXCVBNM"; // sample user input for cipher
    
    string y = "ABCDEFGHIjKLMNOPQRSTVUWXYZ";
    
    int code[25];
    
    for(int i = 0; i < 26; ++i)
    {
        
        if ((int) y[i] > 90)   // For capitalisation
        {
            y[i] -= 32;
        }
        
        code[i] = (int) y[i] - (int) x[i];  // creates cipher array

    }
}

我会使用 C 字符串或普通的旧字符数组来存储您的字符串。我在下面做了,并将它们更改为 char 数组,然后修复了所有问题。

#include <stdio.h>


int main(void)
{

    char x[] = "QWERTYUIOPASDFGHJKLZXCVBNM"; // sample user input for cipher

    char y[] = "ABCDEFGHIjKLMNOPQRSTVUWXYZ";

    int code[26];

    for(int i = 0; i < 26; ++i)
    {

        if ((int) y[i] > 90)   // For capitalisation
        {
            y[i] -= 32;
        }

        code[i] = (int) y[i] - (int) x[i];  // creates cipher array

    }
    for(int i = 0; i < 26; i++) {
        //added this to see what everything looks like after the work is done
        printf("%d",code[i]);
    }
}

还有一些有助于避免过度索引数组的方法是声明一个变量并将其用于迭代,如下所示:

#define ARRAY_SIZE 26

char my_array[ARRAY_SIZE];
for(int i = 0; i < ARRAY_SIZE; i++)
    //do stuff with array

代码有两个问题:

  1. 您循环了 26 次,从 0 开始,到 25 结束,但是您的 code 数组只有 25 项长 int code[25],这意味着最高索引是 24 (因为 0 是第一个索引)。要解决此问题,只需将代码数组的长度更改为 26。
  2. 变量y实际上是一个指向存储在程序数据(bss)部分的只读数据的指针,这意味着如果您尝试修改它(在这种情况下不会发生,但是如果你在 y 中有任何小写字母,它就会),你正在尝试写入只读内存,这会导致另一个段错误。要解决此问题,您需要将数据复制到读写数组中,或者(我所做的)只需将大写版本存储在临时变量中。

此外,为了清楚起见,我建议将大写检查更改为 if (y[i] > 'Z'),因为这会产生相同的效果,但以后更容易回顾。我还重命名了变量 xy 以更好地表明它们的用途,并将 x 大写而不是 y,因为它是包含用户输入的变量。最后,我将 'string' 替换为 'char const *' 以向编译器表明我们以后不应该被允许更改这些值(string 实际上只是 char *)。

#include <stdio.h>

int main(void) {
  char const * cipher_alphabet = "QWERTYUIOPASDFGHJKLZXCVBNM"; // sample user input for cipher    
  char const * alphabet = "ABCDEFGHIjKLMNOPQRSTVUWXYZ";
  int code[26];

  for(int i = 0; i < 26; ++i) {
    char capitalized_letter = cipher_alphabet[i];
    if (capitalized_letter > 'Z') { // capitalize
      capitalized_letter -= 32;
    }
    code[i] = (int)alphabet[i] - (int)capitalized_letter;  // create cipher array
  }
}