誤った出力を与えるCS50シーザー暗号(pset2)
Aug 24 2020
シーザー暗号を使用してメッセージを暗号化するプログラムを実装しようとしています。コードにある種の論理エラーがあり、それを見つけようとして髪を引っ張っています。ロジックは私には理にかなっていますが、間違った出力を取得し続けます。誰かがこの問題について私を案内してくれませんか?
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
//Check that program was run with one command-line argument
if (argc == 2)
{
int n = strlen(argv[1]);
//Iterate over the provided argument to make sure all characters are digits
for (int i = 0; i < n; i++) {
if (isdigit(argv[1][i])) {
//Convert that command-line argument from a string to an int
// int key = atoi(argv[1]);
int key = atoi(argv[1]);
//Prompt user for plaintext
string plaintext = get_string("Enter plain text: ");
printf("ciphertext: ");
//int l = strlen(plaintext);
//Iterate over each character of the plaintext:
for (int j = 0, l=strlen(plaintext); j < l; j++) {
if (isalpha(plaintext[j])) {
if (isupper(plaintext[j])) {
printf("%c", (((plaintext[i] - 65) + key) % 26) + 65);
}
if (islower(plaintext[j])) {
printf("%c", (((plaintext[i] - 97) + key) % 26) + 97);
}
}
else
{
printf("%c", plaintext[i] );
}
}
printf("\n");
return 0;
}
else {
printf("Usage: ./caesar key\n");
return 1;
}
}
}
else
{
printf("Usage: ./caesar key\n");
return 1;
}
}
回答
2 Barmar Aug 24 2020 at 20:46
暗号化を実行するコードは、のすべての文字argv[1]
が数字であることを確認するループ内にあるべきではありません。まず、キーを検証するループを実行します。それが成功した場合は、平文を尋ねて暗号化を実行します。
主な論理的エラーは、あなたがplaintext[i]
多くの場所にいるということです。それはあるはずですplaintext[j]
。
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
//Check that program was run with one command-line argument
if (argc == 2)
{
int n = strlen(argv[1]);
//Iterate over the provided argument to make sure all characters are digits
for (int i = 0; i < n; i++) {
if (!isdigit(argv[1][i])) {
printf("Error: Key must be numeric");
return 1;
}
}
//Convert that command-line argument from a string to an int
int key = atoi(argv[1]);
//Prompt user for plaintext
string plaintext = get_string("Enter plain text: ");
printf("ciphertext: ");
//Iterate over each character of the plaintext:
for (int j = 0, l=strlen(plaintext); j < l; j++) {
if (isupper(plaintext[j])) {
printf("%c", (((plaintext[j] - 'A') + key) % 26) + 'A');
} else if (islower(plaintext[j])) {
printf("%c", (((plaintext[j] - 'a') + key) % 26) + 'a');
} else {
printf("%c", plaintext[j] );
}
}
printf("\n");
return 0;
} else {
printf("Usage: ./caesar key\n");
return 1;
}
}
をネストして内部isupper()
をislower()
チェックする必要もありませんisalpha()
。else if
大文字、小文字、その他すべての3つの相互に排他的な条件をテストするために使用するだけです。
また、ASCIIコードのハードコーディングは避け、文字リテラルを使用してください。