-1

私はcs50 pset2に取り組んできましたが、数日間作業した後、vigenere暗号がダウンしたと思いました。このコードは、ユーザーが指定したアルファベット順の引数 (argv[]) を受け取り、それをキーとして使用して、ユーザーが指定したフレーズ (文字列) をアルファベット順のインデックスの番号で暗号化します。たとえば、引数 'abc' と文字列 'cat' を指定すると、出力は 'cbv' (a 移動 0、b 移動 1、c 移動 2) になります。文字列がより長い場合、引数は最初の文字にラップされ、文字列が終了するまで続きます。

これは私がコードのために持っているものです:

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


int main(int argc, string argv[])
{


    if(argc != 2)
        {
            printf("Try again\n");
            return 1;
        }
    string k = (argv[1]);

    int klen = strlen(k);


    for(int x = 0; x < klen; x++)
        {
            if(isalpha(k[x]))
                {
                    if(isupper(k[x]))
                        {
                            k[x] = tolower(k[x]);
                        }

                        k[x] -= 'a';
                }
            else
                {
                    printf("Try again\n");
                    return 1;
                }
        }

    string code = GetString();

    int clen = strlen(code);

    for(int a = 0, b = 0; a < clen; a++)
        {
            if(isalpha(code[a]))
                {
                    int key = k[b%klen];
                    if(isupper(code[a]))
                        {
                            printf("%c", (((code[a] - 'A') + key)%26) + 'A');
                            b++;
                        }
                    else
                        {
                            printf("%c", (((code[a] - 'a') + key)%26) + 'a');
                            b++;
                        }
                }
            else
                {
                    printf("%c", code[a]);
                }
        }
    printf("\n");
}

コードはキーの長さ+1で機能するようです。たとえば、「aaaa」の引数を入力します

次に、「bbbbb」の文字列を入力し、「bbbbb」を正しく受信します。

ただし、同じ「aaaa」を入力すると

次に、キーより長い文字列を入力 +1 'bbbbbbb' 受信した 'bbbbbNN'

操作の順序に問題があると思いますが、括弧を動かそうとしましたが無駄でした。私のキーが適切にラップされていない理由について、誰かが私を正しい方向に向けることができることを望んでいました.

4

1 に答える 1

0

このようなコードでの最大のリスクは、すべての類似した反復句です。たった 1 つのバグを追跡するのは困難です。また、コードの処理中にキーの処理を行うことは、非効率的です。

これは、コードを処理する前にキーを完全に処理し、処理を 1 つのケースだけに落とし込もうとする作り直しです。それがうまくいくかどうかを確認してください:

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

int main(int argc, string argv[])
{

    if (argc != 2)
    {
        fprintf(stderr, "Try again\n");
        return EXIT_FAILURE;
    }

    string key = strdup(argv[1]);

    size_t key_length = strlen(key);

    for (int x = 0; x < key_length; x++)
    {
        if (isalpha(key[x]))
        {
            if (isupper(key[x]))
            {
                key[x] = tolower(key[x]);
            }

            key[x] -= 'a';
        }
        else
        {
            fprintf(stderr, "Try again\n");
            return EXIT_FAILURE;
        }
    }

    string code = GetString();
    int code_length = strlen(code);

    for (int a = 0, b = 0; a < code_length; a++)
    {
        if (isalpha(code[a]))
        {
            int start = isupper(code[a]) ? 'A' : 'a';

            printf("%c", (((code[a] - start) + key[b++ % key_length]) % 26) + start);
        }
        else
        {
            printf("%c", code[a]);
        }
    }

    printf("\n");

    free(key);

    return EXIT_SUCCESS;
}
于 2016-10-05T16:45:06.650 に答える