c - 如何重复数组中的字符

标签 c cs50 vigenere

我正在尝试用 C 实现 Vigenere 密码,但问题是当我尝试重复其所在数组中使用的 key 时,它会在第 4 个字母后中断。因此,如果 key 是 ABC 并且明文是 HELLO,则返回 HFNLO 而不是 HFNLP。当我查看我的代码时,它在逻辑上是有意义的,但似乎不起作用。有人能看出问题所在吗?

这是代码:

int main(int argc, string argv[])
{
    if(argc != 2)
    {
        printf("usage: ./vigenere k\n");
        return 1;
    }
    //asks for plain text
    printf("plaintext: ");
    string text = get_string();
    string k = argv[1];
    printf("ciphertext: ");

    //checks to see if length of key is shorter than length of plaintext and duplicates it.
    int count = 0;
    while(strlen(k) <= strlen(text))
    {
        k[strlen(k + count)] = k[count];
        count++;
    }

    //changes key to be within 0 - 25 and encrypts plaintext
    for(int i = 0; i < strlen(text); i++)
    {
        if(k[i] >= 'A' && k[i] <= 'Z')
        {
             k[i] = k[i] - 65;
        }
        else if (k[i] >= 'a' && k[i] <= 'z')
        {
            k[i] = k[i] - 97;
        }

        //if statement for plaintext capital letters
        if(text[i] >= 'A' && text[i] <= 'Z')
        {
            text[i] = text[i] - 64;
            text[i] = ((text[i] + k[i]) % 26) + 64;   
        }
        //if statement for plaintext lowercase letters
        else if(text[i] >= 'a' && text[i] <= 'z')
        {
             text[i] = text[i] - 96;
             text[i] = ((text[i] + k[i]) % 26) + 96;   
        }
        //prints final cipher
        printf("%c", text[i]);
    } 
    printf("\n");
    return 0;
}

最佳答案

您应该使用模运算符来计算 key 的偏移量。

这是修改后的版本:

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

int main(int argc, string argv[]) {
    if (argc != 2) {
        printf("usage: ./vigenere k\n");
        return 1;
    }
    string k = argv[1];
    size_t klen = strlen(k);
    if (klen == 0) {
        fprintf(stderr, "vigenere: key must not be empty\n");
        return 1;
    }

    printf("plaintext: ");
    string text = get_string();

    printf("ciphertext: ");

    for (size_t i = 0; text[i] != '\0'; i++) {
        int d = (unsigned char)k[i % klen];
        if (d >= 'A' && d <= 'Z') {
            d -= 'A';
        } else
        if (d >= 'a' && d <= 'z') {
            d -= 'a';
        } else {
            d = 0;
        }

        int c = (unsigned char)text[i];
        if (c >= 'A' && c <= 'Z') {
            c = 'A' + (c - 'A' + d) % 26;   
        } else
        if (c >= 'a' && c <= 'z') {
            c = 'a' + (c - 'a' + d) % 26;   
        }
        putchar(c);
    }
    putchar('\n');
    return 0;
}

关于c - 如何重复数组中的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44686106/

相关文章:

消费者生产者代码未声明的错误linux调试

c - 为什么我的用户定义函数重复两次?

c - 'De-Vigenere' 程序中带有模运算符的负数

c# - c# 中的 autokey vigenere 解密

c++ - 使用 gcc 编译时区分大小写导致错误

c++ - pthread_create : Passing argument by value

c - 为什么我可以单独打印每个字符,但不能整体打印?

c - 由于在 for 循环内使用了 toupper 的条件而给出非大写输入时出现段错误 [C]

c - PSET 2 : Vigenere Cipher partially working?

c文件编译错误