CS50 维吉内尔问题。越界访问、未定义的行为

标签 c cs50 vigenere

这就是我针对 CS50 Vigenère 问题提出的解决方案;我对编程还很陌生,大概只有几周的时间,所以我对我的代码的形式提前表示歉意。

这里的问题是输出不是我期望的。

示例:

./vigenere ABC

输入:你好

输出:hfnLp

./vigenere ABC

输入:你好

输出:HFN,P

./vigenere 培根

输入:上午十一点在公园见我

输出:负 zF av uf pCx bT gzrwEP OZ

(应该是“Negh zf av huf pcfx bt gzrwep oz”)

我一无所知,因为它似乎有点工作,但有些东西不对劲。

我检查了我正在使用的几乎每一个整数,它们都按照我的预期行事。

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

int main (int argc, string argv[])
{
    string k = argv[1]; //key
    string p; //plaintext
    int j = 0; //the counter for key index
    int ci; // the variable for reaching the right shifting value on both uppercase and lowercase letters
    int K;//the value of the key index shift

    if (argc != 2)
    {
        printf("input error\n");
    }
    else
    {
       p = get_string();

       for (int i = 0, n = strlen(p); i < n; i++)
       {
           if (isupper(k[j]))
           {
            ci = 65;
           }
           else
           {
            ci = 97;
           }

           K = k[j % strlen(k)] - ci;

           if (isalpha (p[i]))
           {
                printf("%c", p[i] + K);
                j++;
           }
           else
           {
            printf("%c", p[i]);
           }
       }
       printf("\n");
    }
}

最佳答案

strlen(k) 次迭代之后,isupper(k[j]) 使用超出 k 末尾的索引。

你可以改变:

if (isupper(k[j]))
{
 ci = 65;
}
else
{
 ci = 97;
}

K = k[j % strlen(k)] - ci;

至:

K = toupper(k[j % strlen(k)]) - 'A';

(请注意,这依赖于 C 标准未保证的属性,即字母的字符代码是连续的且按字母顺序排列。)

关于CS50 维吉内尔问题。越界访问、未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55493081/

相关文章:

在 C 程序中将红绿蓝文件组合成 .ppm 文件

c - PPM 将二进制转换为 ASCII - 无法解释的质量损失

c - 读取两行整数

java - 我在哪里可以找到 Vigenere 密码的 Java 源代码?

c - 图标显示在窗口上但不显示在 .exe 文件上 (gtk3 windows7)

CS50 Caesar - ASCII 字母和输出格式

将字符转换为位于 argv[1] 内字符串内的 int

c - for循环问题

python - Python 3 中的 for 循环出现问题 : getting the index in string2 of an element from string1

c - Vigenere Cipher - 公式解释