简体   繁体   中英

How to store a values with a min and max size in c

I'm trying to create a program which asks for a 13-16 digit credit card number, and re-prompts if the user enters non-numerical values. So far my program works when I enter 16 digit values; however, it re-prompts if I enter anything less.

How do I get my program to accept a minimum of 13 digits and max of 16 digits?

#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);
}

You can use strcspn to locate the end of the char array in the while condition, you can return the size of the char array till it finds '\0' (or '\n' since you don't seem to be removing it from the array), you can then use this to set a minimum size for the input.

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

You could also remove the '\n' from buf , in which case you can use strlen :

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

The max size of buf will be 16 because you limit the size in fgets to 17 , so it will store 16 characters plus the null-terminator, you can reduce the size of your array to 17 , since the 18th element is useless.

Also be aware that long is not always 8 bytes, https://en.wikibooks.org/wiki/C_Programming/limits.h

This being said, there is an inherit problem with the code, it consumes everything, aphabetic caracters, spaces, etc., so if you have an input of 1234 1234 1234 1234 , only 1234 will be converted by strtol .

In theexample below I'm removing everything that is not a digit and maintaining all your other specs:

Running sample

#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);
}

If we're specifically talking about credit card numbers, you might want to enforce it only by the number of digits the user enters and not the number of total characters since credit card numbers are often entered with spaces or dashes between them.

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM