【问题标题】:What's wrong with my cs50 vigenere code? I am close on the output我的 cs50 vigenere 代码有什么问题?我接近输出
【发布时间】:2017-12-20 16:02:16
【问题描述】:

我已经为此花费了几个小时,但我仍然陷入困境。当我进行检查时,我得到以下输出。这些错误与我打印出来的方式有关吗?

  • :) vigenere.c 存在
  • :) vigenere.c 编译
  • :( 使用“a”作为关键字将“a”加密为“a” \ 预期输出,但不是“密文:a\u0004ù\u001bÿ\n”
  • :) 使用“baz”作为关键字将“barfoo”加密为“caqgon”
  • :) 使用“BaZ”作为关键字将“BaRFoo”加密为“CaQGon”
  • :) 使用“BAZ”作为关键字将“BARFOO”加密为“CAQGON”
  • :( 使用“baz”作为关键字将“world!$?”加密为“xoqmd!$?” \ 预期输出,但不是 "c​​iphertext: xoqmd!$?í\b@\n"
  • :( 使用“baz”作为关键字将“world, say hello!”加密为“xoqmd, rby gflkp!” \ 预期输出,但不是“密文:xoqmd,rby gflkp!^¿µÿ\n”
  • :) 处理缺少 argv[1]
  • :) 处理 argc > 2
  • :) 拒绝“Hax0r2”作为关键字

代码如下:

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

#define alpha_length 26

char secret(char character, int key);

int main(int argc, string argv[]) {
    //check that there are only two strings
    if (argc != 2) {
        printf("Usage: ./vignere k\n");
        return 1;
    }
    //check that argv1 is alphabetical
    string code = argv[1];
    for (int t = 0; t < strlen(code); t++) {    
        if (!isalpha(code[t])) {
            printf("Alphabetical only!\n");
            return 1;
        }
    }
    //get string from user to encrypt
    printf("plaintext: ");
    string plaintext = get_string();

    //array created out of user inputted plain text
    char cypher[strlen(plaintext)];

    //j counts the number of alphabetical characters so that it resets based on argv length
    int j = 0; 
    //iterate over characters in array.  If they are alpha then apply the function secret
    for (int i = 0; i < strlen(plaintext); i++) {
        if (isalpha(plaintext[i])) {
            int index = j % strlen(code);
            int code_index = toupper(code[index]) - 'A' ;
            cypher[i] = secret(plaintext[i], code_index);
            j = j + 1;
        } else {
            cypher[i] = plaintext[i];
        }
    }
    printf("ciphertext: %s\n", cypher);

    return 0;
}  

char secret (char character, int key) {
    char shift;

    // if the character is upper case then start with uppercase A and shift based on the appropriate character from argv1
    if (isupper(character)) {
        shift = (int)character -'A';
        shift = shift + key;
        shift = (shift % alpha_length) + 'A';
    } else {
        // else start wit lower case a
        shift = (int)character - 'a'; 
        shift = shift + key;
        shift = (shift % alpha_length) + 'a';
    }
    return (char)shift;
}

【问题讨论】:

  • 1) char cypher[strlen(plaintext)]; --> char cypher[strlen(plaintext)+1]; +1 表示 NUL 字符。 %s of printf 要求字符串以 NUL 字符结尾。
  • 因此您还需要在编码循环之后终止该字符串,然后将其传递给printf,使用cypher[i] = '\0';

标签: c cs50 vigenere


【解决方案1】:

您的代码存在多个问题:

  • 不要使用来自&lt;cs50.h&gt;string typedef:它隐藏了您正在操作的对象的性质,一个简单的char * 指针,您应该学会无所畏惧地掌握它。

    1234563 p>
  • 您希望cypher 成为 C 字符串,因此您必须为空终止符分配一个额外的字节并将其存储在那里:

    char cypher[strlen(plaintext) + 1];
    
  • 密码用i拼写。

这是修改后的版本:

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

#define alpha_length 26

char secret(char character, int key);

int main(int argc, char *argv[]) {
    //check that there are only two strings
    if (argc != 2) {
        printf("Usage: ./vignere k\n");
        return 1;
    }
    //check that argv1 is alphabetical
    char *code = argv[1];
    int code_len = strlen(code);
    for (int t = 0; t < code_len; t++) {    
        if (!isalpha((unsigned char)code[t])) {
            printf("Alphabetical only!\n");
            return 1;
        }
    }
    //get string from user to encrypt
    printf("plaintext: ");
    char *plaintext = get_string();
    int text_len = strlen(plaintext);

    //array created out of user inputted plain text
    char cipher[text_len + 1];

    //j counts the number of alphabetical characters so that it resets based on argv length
    int j = 0; 
    //iterate over characters in array.  If they are alpha then apply the function secret
    for (int i = 0; i < text_len; i++) {
        if (isalpha((unsigned char)plaintext[i])) {
            int index = j % code_len;
            int code_index = toupper((unsigned char)code[index]) - 'A';
            cipher[i] = secret(plaintext[i], code_index);
            j = j + 1;
        } else {
            cipher[i] = plaintext[i];
        }
    }
    cipher[text_len] = '\0';
    printf("ciphertext: %s\n", cipher);

    return 0;
}  

char secret (char character, int key) {
    int shift;

    // if the character is upper case then start with uppercase A and shift based on the appropriate character from argv1
    if (isupper((unsigned char)character)) {
        shift = (int)character - 'A';
        shift = shift + key;
        return 'A' + (shift % alpha_length);
    } else {
        // else start with lower case a
        shift = (int)character - 'a'; 
        shift = shift + key;
        return 'a' + (shift % alpha_length);
    }
}

【讨论】:

  • for (int i = 0, text_len = ... cipher[i] = '\0'; --> int i = 0; for (int text_len = ... cipher[i] = '\0';
  • @BLUEPIXY:当然可以!谢谢。我一直在犯这个错误,for 初始表达式定义的范围让我感到困惑。
  • text_len 现在未声明。 :-)
  • @BLUEPIXY:我希望我终于做对了。我也可以使用printf("ciphertext: %.*s\n", text_len, cipher);,但教学价值较低。
  • @BLUEPIXY:已修复。我应该编译这些玩具程序,让编译器帮助我避免愚蠢的拼写错误和范围错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多