Как сохранить значения с минимальным и максимальным размером в c - PullRequest
2 голосов
/ 13 апреля 2020

Я пытаюсь создать программу, которая запрашивает номер кредитной карты 13-16 di git и повторно запрашивает, если пользователь вводит нечисловые значения. Пока что моя программа работает, когда я ввожу значения 16 di git; тем не менее, он повторяет, если я введу что-нибудь меньшее.

Как заставить мою программу принимать минимум 13 цифр и максимум 16 цифр?

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

int main(void)
{
    long cn;
    char buf[18], *endptr;

    do
    {
        printf("card number please: ");
        fgets(buf, 17, stdin);
        cn = strtol(buf, &endptr, 0);
    } while (*endptr != '\0' || endptr == buf);

    printf("%ld\n", cn);
}

Ответы [ 2 ]

2 голосов
/ 13 апреля 2020

Вы можете использовать strcspn, чтобы найти конец массива char в условии while, вы можете вернуть размер массива char, пока он не найдет '\0' ( или '\n', поскольку вы, похоже, не удаляете его из массива), затем вы можете использовать это, чтобы установить минимальный размер для ввода.

#include <string.h>
//...
do{
//...
while (strcspn(buf, "") < 14); //less than 13 chars will repeat the cycle
//...

Вы также можете удалить '\n' от buf, в этом случае вы можете использовать strlen:

//...
do{
    fgets(buf, 17, stdin);
    buf[strcspn(buf, "\n")] = '\0';
while (strlen(buf) < 13); //by removing '\n' you can use strlen
//... 

Максимальный размер buf будет 16, поскольку вы ограничите размер fgets до 17, поэтому он будет хранить 16 символов плюс нулевой терминатор, вы можете уменьшить размер вашего массива до 17, так как элемент 18th бесполезен.

Также имейте в виду, что long не всегда 8 байтов, https://en.wikibooks.org/wiki/C_Programming/limits.h

При этом существует проблема наследования кода, он потребляет все, например, c символов, пробелов и т. д. c. , поэтому, если у вас есть ввод 1234 1234 1234 1234, только 1234 будет преобразовано в strtol.

В приведенном ниже примере я удаляю все, что не является ди git и сохраняю все остальные ваши спецификации:

Рабочий образец

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

int main()
{
    long long cn; //long long is never smaller than 8 bytes
    int i, c;
    char buf[17];

    do {
        i = 0;
        printf("card number please: ");
        while ((c = fgetc(stdin)) != '\n' && c != EOF && strlen(buf) < 17) //max size 16
        {
            if (isdigit(c)) //only digits
                buf[i++] = c;
        }
        buf[i] = '\0';
    } while (strlen(buf) < 13); //min size 13

    cn = strtoll(buf, NULL, 10); //strtoll for long long

    printf("%lld\n", cn);
}
1 голос
/ 14 апреля 2020

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

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

int numberofdigits(char *str)
{
    int i = 0, n = 0;
    while(str[i])
    {
        n += !!(isdigit(str[i]));
        i++;
    }

    return n;
}

int main()
{
    char str[100];
    int digits; 

    do
    {
        printf("Enter a credit card number: ");
        fgets(str, 100, stdin);

        digits = numberofdigits(str);
        printf("Read %d digits.\n", digits);
    }
    while((digits < 13) || (digits > 16));

    printf("Thanks for entering \"%s\"\n", str);

    return 0;
}
...