Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to verify input format without using arrays, ex input "OIL2932"

Tags:

c

Hi I'm having a really hard time reading user input in C a specific way...

I want to read a users input, in which case my program will verify the first three characters as characters and the last four digits as digits. And I don't know how to make sure that their input is 7 characters in total (3 chars, 4 ints) ex: ULI0788.

I don't want to use arrays, ex arr[12];

Currently I am at the point where I'm learning memory allocation & pointers, thus I am encouraged to use this rather than arrays if possible

for example

char itemID;
printf("Enter an ID of ITEM. (max 3 characters, 4 digits)");
scanf("%s", itemID);

I've done some googling and tried user suggestions but none do both of what I'm looking for, verifying each character/digit and setting a max of 7 total characters/digits. Or I just don't understand properly how to use the suggestions

googled
googled2
googled3
googled4
googled5
googled6
googled7
googled8
googled9
googled10

like image 473
Quibble Coinbiter Avatar asked Nov 16 '25 09:11

Quibble Coinbiter


2 Answers

"I want to read a users input, in which case my program will verify the first three characters as characters and the last four digits as digits. And I don't know how to make sure that their input is 7 characters in total (3 chars, 4 ints)...I don't want to use arrays"

Without the ability to use C strings, the above is constrained to simply inputting a series of characters, then treating and testing them as discrete items:

bool test7char(void)
{
    int Char;

    for(int i=0;i<7;i++)
    {
        Char = getc(stdin);
        if(i<3)
        {
             if(!isalpha(Char)) return false;
        }
        else if(!isdigit(Char)) return false;
    }
    return true;
}

Usage:

int main(void)
{
    printf("Enter an ID of ITEM. (max 3 characters, 4 digits)");
    while(!test7char())
    {
        printf("Mistake - Re-enter an ID of ITEM. (max 3 characters, 4 digits)");
    }
    
    return 0;
}

EDIT - "I am just trying to figure out how to answer my question using memory allocation & maybe pointers"

Using pointer: (In memory, this pointer will point to a series of alphanumeric characters, terminated by \0, i.e. a string.)

#define STR_SIZE 7 + 1
BOOL test7char(const char *str);

int main(void)
{
    char *str = calloc(STR_SIZE, 1);
    if(str)
    {
        printf("Enter an ID of ITEM. (max 3 characters, 4 digits)");
        if(fgets(str, STR_SIZE, stdin))
        {
            while(!test7char(str))
            {
                printf("\nMistake - Re-enter an ID of ITEM. (max 3 characters, 4 digits)");
                if(!fgets(str, STR_SIZE, stdin))
                {
                    //message user of error
                    break;
                }
            }
        }
        free(str);
    }
    
    return 0;
}

bool test7char(const char *str)
{
    if(!str) return false;
    if(strlen(str) != STR_SIZE -1) return false; 

    for(int i=0;i<7;i++)
    {
        if(i<3)
        {
             if(!isalpha(str[i])) return false;
        }
        else if(!isdigit(str[i])) return false;
    }
    return true;
}

    
like image 65
ryyker Avatar answered Nov 19 '25 00:11

ryyker


I would advise you to use both fgets and sscanf:

  • fgets allows you to read a certain number of characters (which can be read from stdin).
  • sscanf allows you to read formatted input from a string (which you got from fgets).

By combining those, you can read 7 characters from standard input (8 if you add the \0) and then parse those to get the two values you're looking for.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    // 8 chars long for string and terminating `\0`
    char *ID = calloc(8, 1);
    
    // extra char for same reason as above
    char *IDchar = calloc(4, 1);
    int IDnum, processed;
    
    // get the string and verify it's 7 characters long
    if (fgets(ID, 8, stdin) && strlen(ID) == 7) 
        sscanf(ID, "%3s%4d%n", IDchar, &IDnum, &processed);
    if (processed == 7)
        printf("success");
    else
        printf("failure");
}

The %n will collect the number of characters processed by the sscanf, ensuring you parsed the right number of characters. note that this is a VERY dangerous parameter, and you should always verify your input length before using it.

Edit:

If you do not want to use arrays at all, and only want to verify the input format without storing or reusing it, you can use getc to read the characters one at a time and verify their value:

#include <stdio.h>
#include <ctype.h>
int isEnd(int c)
{
    return c == '\n' || c == EOF;
}
void main()
{
    int tmp;
    int valid = 1;
    //check the first 3 characters
    for(int v = 0; v < 3 && valid; v++)
    {
        // read a char on standard input
        tmp = fgetc(stdin);
        // check if tmp is a letter
        valid = islower(tmp) || isupper(tmp);
    }
    //check the next 4 characters
    for(int v = 0; v < 4 && valid; v++)
    {
        // read a char on standard input
        tmp = fgetc(stdin);
        // check if tmp is a numeral
        valid = isdigit(tmp);
    }
    if (valid)
    {
        printf("format OK\n");
        // Check that the input is finished (only if format is OK)
        tmp = fgetc(stdin);
        if (isEnd(tmp))
            printf("length OK\n");
        else
            printf("length KO: %d\n", tmp);
    }
    else
    {
        printf("format KO\n");
    }
}

As I said before, this will only check the validity of the input, not store it or allow you to reuse it. But it does not use arrays.

Edit 2:

Another thing to watch out for with fgetc or getc is that, though it will manage longer inputs properly, it will get stuck waiting for the chars to be provided if there aren't enough. Thus make sure to exit the moment you read an incorrect character (if it's an end-of-line char, there won't be any more coming)

Edit 3:

Of course I'd forgotten malloc. Edited the first answer.

like image 28
Adalcar Avatar answered Nov 19 '25 00:11

Adalcar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!