C 维格纳密码额外字符

C 维格纳密码额外字符,c,encryption,vigenere,cs50,C,Encryption,Vigenere,Cs50,我把维格纳密码编码成CS50的一部分。这是我的密码 #include<cs50.h> #include<string.h> #include<stdlib.h> #include<stdio.h> #include<ctype.h> int main(int argc, string argv[]) { if(argc != 2) { printf("Bad Argument!\n");

我把维格纳密码编码成CS50的一部分。这是我的密码

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

int main(int argc, string argv[])
{
    if(argc != 2)
    {
        printf("Bad Argument!\n");
        return 1;
    }

    for(int k = 0; k <= strlen(argv[1]) - 1; k++)
    {
        if (isalpha(argv[1][k]) == 0)
        {
            printf("Bad Argument!\n");
            return 1;
        }
    }

    string s = GetString();
    char a[strlen(s)];

    int i, j = 0;
    int l = strlen(argv[1]);

    for (i = 0; i < strlen(s); i++)
    {
        int k = (int)(tolower(argv[1][j%l]) - 'a');

        if (s[i] >= 'A' && s[i] <= 'Z')
        {
            a[i] = (s[i] - 'A' + k) % 26 + 'A';
            j++;
        }
        else if (s[i] >= 'a' && s[i] <= 'z')
        {
            a[i] = s[i] - 'a' + k) % 26 + 'a';
            j++;
        }
        else
            a[i] = s[i];
    }

    printf("%s\n", a);

}

我做错了什么?

您忘记在加密字符串中添加尾随的空字节。因此,内存中字符串(这里是堆栈上的一些数据)之后的所有内容都会打印出来,直到遇到一个随机的空字节

因此,为额外的空字节分配
strlen+1

char a[strlen(s) + 1];
并将
a
的最后一个元素设置为
'\0'

a[strlen(s)] = '\0';

1在此表示:如果
x
位于内存位置
0x00
,则后面的内存位置为
0x01


注:

  • 我建议引入一个变量,比如
    size\t printstr\u len=strlen(s)
    并在任何地方使用它来代替普通的strlen(s),以提高性能

    • 您忘记了
      NUL
      终止符

      C没有内置的“字符串”类型,你的CS50讲师在“CS50.h”中为“字符串”创建了一个typedef,这对你是一种伤害。在C语言中,“字符串”是一个字符数组,末尾有一个
      NUL
      终止符。数组的大小必须是字符串长度加1

      因此,代码中的第一个错误是

      char a[strlen(s)];
      
      应该是哪一个

      size_t length = strlen(s);
      char a[length+1];
      
      您的代码稍微优化一下,就可以替换

      for (i = 0; i < strlen(s); i++)
      

      如果你对学习C很认真,我建议你转到另一所大学。理解C语言中的字符串是编写稳定、可靠、安全代码的关键。因为你的教授对你隐瞒了细节,你什么也学不到。

      我认为一个班一个教授不足以成为离开大学的理由。
      for (i = 0; i < strlen(s); i++)
      
      for (i = 0; i < length; i++)
      
      a[length] = '\0';