CS50 PSet 2 - Vigenere - Убедитесь, что ключевое слово написано в алфавитном порядке

В настоящее время я работаю над шифром Виженера в CS50 с использованием языка C. Требуется создать программу, которая шифрует некоторый открытый текст на основе ключевого слова (оба из которых вводятся пользователем). Он будет шифроваться на основе шифра Виженера. Мне сложно описать словами, что такое шифр Виженера, поэтому вот пример из спецификации CS50:

Если бы сам Виженер хотел передать кому-то ПРИВЕТ конфиденциально, используя ключевое слово, скажем, ABC, он бы зашифровал H ключом 0 (т. Е. A), E с ключом 1 (т. Е. B) и первый L с ключом 2 (то есть C), в этот момент у него не будет букв в ключевом слове, и поэтому он повторно использовал (часть) его, чтобы зашифровать второй L с ключом 0 ( то есть, A) снова, и O с ключом 1 (то есть B) снова. И поэтому он написал HELLO как HFNLP.

Ключевое слово должно быть строкой из всех букв алфавита и должно быть указано в качестве второго аргумента командной строки, то есть argv [1] в моем приведенном ниже коде. Проблема, с которой я столкнулся, заключается в том, что я не могу заставить программу отклонять ключ, если он не алфавитный, и продолжать, если он полностью алфавитный. Я пробовал сделать это так (см. Код ниже), и он не возвращает сообщение об ошибке printf, если я включаю число в argv [1]. Пожалуйста, может кто-нибудь посоветовать, что не так? Приносим извинения, если формат не очень хорош ...

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

// declare command line argument variables
int main(int argc, string argv[])
{

string k = argv[1];

//return error if there aren't two command line arguments
if (argc != 2)
    {
        printf("Usage: ./vigenere k\n");
        return 1;
    }

//make sure key is all alphabetical
for (int i = 0; i < strlen(k); i++)

 {
    if(isalpha(k[i]))
    {
    return 0;
    }

    else
    {
    return 1;
    printf("Please ensure all characters are alphabetical.\n");
    }
 }
}

Я также пробовал это, а не то, что находится внутри цикла for выше, и это не сработало:

if(!isalpha(k[i]))
    {
    return 1;
    printf("Please ensure all characters are alphabetical.\n");
    }

person joshkeisler95    schedule 17.01.2017    source источник


Ответы (1)


   if(isalpha(k[i]))
    {
    return 0;
    }

выходит из программы, как только в argv[1] появляется алфавит. Вместо этого вы хотите продолжить цикл до тех пор, пока не будут отмечены все символы. Ну действуй:

 for (size_t i = 0; i < strlen(k); i++)
 {
    if(!isalpha(k[i]))
    {
    printf("Please ensure all characters are alphabetical.\n");
    return 1;
    }
 }

Вам также необходимо поставить проверку аргументов перед использованием argv[1].

if (argc != 2)
    {
        printf("Usage: ./vigenere k\n");
        return 1;
    }

string k = argv[1];
...
person P.P    schedule 17.01.2017
comment
спасибо за помощь :) Я явно не понимал, что на самом деле дало возврат. - person joshkeisler95; 17.01.2017
comment
Я изменил оператор if, чтобы он не прерывался немедленно, когда он находит альфа-символ, и сразу же вылетает, когда есть не-альфа-символ. В основном, когда цикл завершается, argv[1] прошел альфа-тест. - person P.P; 17.01.2017
comment
Извините еще за одну вещь - что такое size_t? - person joshkeisler95; 17.01.2017
comment
size_t - целочисленный тип; использовал его вместо int, потому что технически цикл может переполнять int, поскольку strlen() возвращает size_t. Это, вероятно, не имеет значения в вашей игрушечной программе, но лучше выработать привычку использовать правильные типы. - person P.P; 17.01.2017
comment
Причудливое возражение - на практике очень мало систем и нет настольных или серверных систем, в которых исполняемому файлу не сообщается имя его программы, поэтому argc всегда по крайней мере один, даже когда не передаются аргументы, поэтому argv[1] определяется как нулевой указатель (потому что argv[argc] == NULL). Итак, в этом случае можно было использовать string k = argv[1]; перед проверкой количества аргументов. Однако использование argv[2] не обязательно будет безопасным. И в целом вы правы - убедитесь, что аргумент, который вы собираетесь использовать, существует, прежде чем пытаться его использовать. Итак, вы в основном правы. - person Jonathan Leffler; 17.01.2017