Как я должен заставить пользователей вводить информацию, которую я хочу? - PullRequest
1 голос
/ 06 января 2020

Я только начал изучать информатику.

Я учусь в CS50, преподавая в Гарварде онлайн. Что ж, я работаю над этой одной проблемой, когда мне нужно получить ключ от пользователя в командной строке, затем открыть текст, а затем сдвинуть этот текст для количества ключей в ASCII, чтобы создать зашифрованный текст.

вот то, что у меня есть до сих пор.

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

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
    }

    {
        string plaintext = get_string("plaintext:  ");

        int key = atoi(argv[1]);
        int n = strlen(plaintext);
        char chr[n];

        printf("ciphertext: ");
        for (int i = 0; i < n; i++)
        {
            chr[i] = plaintext[i];
            if (isalpha(chr[i]))
            {
                if (isupper(chr[i]))
                {
                    chr[i] = (chr[i] - 65 + key) % 26 + 65;
                    printf("%c",chr[i]);    
                }
                else if (islower(chr[i]))
                {
                    chr[i] = (chr[i] - 97 + key) % 26 + 97;
                    printf("%c",chr[i]);    
                }            
            }
            else
            {
                printf("%c",chr[i]);        
            }
        }
    printf("\n");
    }
}

ну, я знаю, что это кажется очень гибким, но, блин, моя вторая неделя в программировании, когда я работаю полный рабочий день.

В любом случае, я ' я пытаюсь заставить пользователя запустить эту программу, используя ./caesar «любое число для ключа».

, если пользователь вводит какие-либо другие вещи, то я хотел бы напечатать «Использование: ./ ключ цезаря \ n "

До сих пор я мог думать только о том, чтобы сделать оператор if с аргументом arg c! = 2, чтобы я мог по крайней мере убедиться, что пользователь вводит только одну команду сверху имени программы.

, но проблема в том, что если пользователь вводит другие вещи, такие как ./caesar HELLO ./caesar YolO

, программа все равно запускается.

Я пытаюсь понять, что я могу сделать, чтобы этого не произошло. * 10 20 *

Очень ценю ваше время, чтобы прочитать это и помочь.

Ответы [ 2 ]

5 голосов
/ 06 января 2020

Это причина, по которой старая функция atoi была заменена на strtol. Первые только пытаются преобразовать начальную цифру c часть из заданной строки, в то время как последняя также сообщает, что остается после преобразованной части.

Таким образом, чтобы убедиться, что пользователь дал число в качестве единственного аргумента , вы можете сделать:

int main(int argc, char *argv[]) {
    long key;
    int reject = 0;

    if (argc != 2) {                         // ensure one argument
        reject = 1;
    }
    else {
        char *end;
        key = strtol(argv[1], &end, 10);    // ensure not empty and numeric
        if ((*end != 0) || (end == argv[1])) reject = 1;
     }
    if (reject) {
        printf("Usage: %s key\n", argv[0]);
    return 1;
}

sscanf тоже можно использовать. Он даже допускает пустые символы после числа, что не должно происходить, поскольку массив argv отделен пробелом:

int main(int argc, char *argv[]) {
    int key;
    char empty[2];

    if ((argc != 2) || (sscanf(argv[1], "%d%1s", &key, empty) != 1)) {
        printf("Usage: %s key\n", argv[0]);
        return 1;
    }
    ...
0 голосов
/ 06 января 2020

Перефразируя ваш вопрос: вы хотите выполнить проверку при вводе пользователем, где единственными допустимыми значениями ввода являются цифры c строки: 123 и 4534 и 000 все могут считаться действительными, но hello world и f00 и one hundred thirty two недопустимы.

В большинстве языков программирования, включая C, строки являются более или менее просто массивами отдельных char элементов (другими словами, char является примитивным типом данных, но string - нет. ... C вообще не имеет типа данных string подсказка: посмотрите, как вы объявили main). Итак, как вы можете использовать это в своих интересах, чтобы проверить вклад в эту программу? Достаточно просто: каждый символ во входной строке должен происходить из домена [0123456789] (плюс нулевой терминатор \0 в конце ...).

Итак, чтобы решить эту проблему, вам просто нужно реализовать проверка, которая проверяет, что введенное значение имеет это свойство. Есть несколько способов сделать это, возможно, самый простой из которых:

int num;
int y = scanf("%d", &num);

, затем проверьте значение y. Для него будет задано количество допустимых входных данных, которые scanf прочитал (таким образом, будет 1, если задано число).

Примечание:
, как упомянуто в комментариях, это также будет принимать такие вещи, как 123abc (это будет убирать цифры и игнорировать символы в конце). Если вам абсолютно необходимо иметь только цифры для ввода, scanf может оказаться неправильной функцией. В этом случае лучше использовать fgets для чтения ввода как строки, а затем циклически повторять каждый вход, чтобы убедиться, что он входит в допустимую область ввода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...