Как проверить каждый символ аргумента командной строки? Цезарь PSET2 - PullRequest
0 голосов
/ 23 мая 2019

Мне нужно проверить, есть ли в аргументе командной строки нецифровый символ.Например: ./problem 20x должен распечатать "Не цифра", поскольку он содержит х.Мой код, кажется, не перебирает все символы в аргументе командной строки.

Я в основном пробовал разные типы циклов, но, похоже, не работает.

string s = argv[1];

for (int i = 0, n = strlen(s); i < n; i++)
{
    while (s[i] != '\0')
    {
        if (isdigit (s[i]) == false)
        {
            printf(" Not a digit\n");
            return 1; 
        }
    }
    int k = atoi(s);
    printf("Success\n");
    return 1;
    }
}

Я ожидаю, что на выходе «20x» будет напечатано «Не цифра».Также вывод "x20" должен быть "Не цифра"

1 Ответ

0 голосов

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

enum bool_t {
    FALSE,
    TRUE
};

int main(int argc, char *argv[])
{
    if (argc == 1) {
        fprintf(stderr, "No input(s).\n");

        return EXIT_FAILURE;
    }

    while (*++argv) {
        int found_invalid_character = FALSE;

        for (size_t i = 0; i < strlen(*argv); ++i) {
            if (!isdigit((*argv)[i])) {
                found_invalid_character = TRUE;
                break;
            }
        }

        if (found_invalid_character) {
            printf("%s is not a valid integer.\n", *argv);
            continue;
        }

        int n = atoi(*argv);
        printf("%d is a valid integer.\n", n);
    }

    return EXIT_SUCCESS;
}

Выход:

x20 is not a valid integer.
20x is not a valid integer.
20 is a valid integer.

Помните, что argv - это массив указателей на массивы символов с нулевым символом в конце, поэтому вы всегда сможете выполнить итерацию по «строке», проверив, нажали ли вы нулевой терминатор. Вы можете переопределить функции в string.h с нуля, если хотите, используя это практически для всего. Вот, например, функция strlen.

size_t my_strlen(const char* s) {
    size_t len = 0;

    while (*s++)
        ++len;

    return len;
}

Каждый раз, когда оценивается условие while, указатель s увеличивается и разыменовывается. Каждое значение *s будет некоторым значением ASCII и, следовательно, ненулевым, пока не будет найден терминатор nul, в этот момент оператор ++len не будет выполнен. Вот почему strlen условно возвращает длину строки минус нулевой терминатор .

Таким образом, в основном цикл for, который я использовал в своем примере для вашей программы, который зависел от длины строки ввода, косвенно зависел от нахождения нулевого терминатора входной строки. Вот почему вы также можете использовать цикл while при проверке нулевого терминатора.

<ч />

Кроме того, я заметил, что вы возвращаете 1 в конце как ваших успешных, так и неудачных веток, которыми я был немного озадачен. Возвращение 1 условно означает ошибку, и фактически stdlib.h определяет макрос EXIT_FAILURE как 1. Я сам использую эти макросы, хотя, если вы заметите, я определил TRUE и FALSE, используя перечисление, что делает их лексически видимые для программы как «FALSE» и «TRUE», а также 0 и 1, которые являются их соответствующими значениями, а не просто заменяются текстом на 0 и 1 препроцессором.

Кроме того, вы не включили свои заголовки или предыдущие определения, но я предполагаю, что вы работаете в Windows, потому что false не является допустимым значением в C без определения вручную, тогда как Visual Studio, будучи Компилятор C ++, это позволяет. Я поднимаю это, потому что меня смутила строка string s = argv[1]. Это может означать, что вы работаете с компилятором C ++ и используете печально известный using namespace std;, или вы напечатали def'd: typedef const char* string. Мне не нравится ни один из вариантов лично, но каждому свой.

В любом случае, надеюсь, это поможет, удачи.

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