【问题标题】:Vigenere Cipher Extra CharactersVigenere 密码额外字符
【发布时间】:2015-11-20 22:32:47
【问题描述】:

我将 Vigenere Cipher 编码为 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);

}

这是我的 pset2 vigenere.c 代码。但是,一旦我编译并运行它,我会在密文末尾得到其他字符,例如:

因此,Check50 在某些情况下会接受答案,而在其他情况下则不会。

:( encrypts "a" as "a" using "a" as keyword
   \ expected output, but not "a\u001c������\n"
:( encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword
   \ expected output, but not "xoqmd, rby gflkp!v��\t��\n"
:) encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword
:) encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword

我做错了什么?

【问题讨论】:

    标签: c encryption vigenere cs50


    【解决方案1】:

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

    所以,为额外的空字节分配strlen(s) + 1

    char a[strlen(s) + 1];
    

    并将a的最后一个元素设置为'\0'

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

    1 在这里表示:如果x 在内存位置0x00,则以下内存位置是0x01


    注意事项:

    • 为了性能起见,我建议引入像 size_t plainstr_len = strlen(s); 这样的变量并在任何地方使用它来代替普通的 strlen(s)

    【讨论】:

      【解决方案2】:

      您忘记了NUL 终结符。

      C 没有 "string" 的内置类型,并且您的 CS50 讲师在“cs50.h”中为“string”创建 typedef 对您不利。在 C 中,"string" 是一个字符数组,末尾带有 NUL 终止符。数组的大小必须是字符串长度加一。

      所以你的代码中的第一个错误是

      char a[strlen(s)];
      

      应该是

      size_t length = strlen(s);
      char a[length+1];
      

      您的代码的轻微优化是替换

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

      for (i = 0; i < length; i++)
      

      但您的代码中最大的问题是缺少NUL 终止符,您可以通过在循环结束后添加以下行来解决此问题

      a[length] = '\0';
      

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

      【讨论】:

      • 我认为一个班上的一位教授不足以成为离开大学的理由。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多