Question Details

No question body available.

Tags

c

Answers (2)

Accepted Answer Available
Accepted Answer
October 6, 2025 Score: 3 Rep: 27,384 Quality: Expert Completeness: 100%

The C programming language is not a reflective language. Therefore, it is not possible for a C program to change its own code at run-time (but is possible to a certain extent at compile-time, using the preprocessor).

Nevertheless, the C language does offer everything you need to accomplish what you want.

Instead of hard-coding the values 0, 1, 2 and 3, I suggest that you create an enumeration:

typedef enum
{
    STOCKSTATUSEMPTY,
    STOCKSTATUSBELOWMINIMUM,
    STOCKSTATUSATMINIMUM,
    STOCKSTATUSABOVEMINIMUM

} stockstatus;

That way, when you write

  • STOCKSTATUSEMPTY, it will be equivalent to writing the value 0,
  • STOCKSTATUSBELOWMINIMUM, it will be equivalent to writing the value 1,
  • STOCKSTATUSATMINIMUM, it will be equivalent to writing the value 2, and
  • STOCKSTATUSABOVEMINIMUM, it will be equivalent to writing the value 3.

Using these identifiers instead of the raw numbers will make your code longer, but it will be much easier to read, understand and maintain.

Instead of returning the data type int, you can change your function checkStocker to return a value of this enumeration data type:

stockstatus stockChecker( char productName )

Your function will still be internally returning a number, but by using the data type stock
status instead of int, it is clearer what the meaning of this number is.

Instead of hard-coding all individual products with if statements, you can create an array of structures of all products:

typedef struct
{
    char name;
    int amount;
    int min;

} product;

product products[] = { { 'A', 12, 5 }, { 'B', 7, 3 }, { 'C', 9, 4 }, { 'D', 8, 4 } };

If all products are named A, B, C, D, etc., and there are no gaps, then you don't need to explicitly store the name of the product, as its name is implied by its position in the array. So you can simplify the code above to the following:

typedef struct
{
    int amount;
    int min;

} product;

product products[] = { { 12, 5 }, { 7, 3 }, { 9, 4 }, { 8, 4 } };

You can then write the function checkStocker like this:

stockstatus stockChecker( char productName )
{
    // lookup the product in the products array, by converting
    // the ASCII code of the product to an array index
    product *p = &products[ productName - 'A' ];

if ( p->amount == 0 ) return STOCK
STATUSEMPTY;

if ( p->amount > p->min ) return STOCK
STATUSABOVEMINIMUM;

if ( p->amount < p->min ) return STOCKSTATUSBELOWMINIMUM;

return STOCK
STATUSATMINIMUM; }

The array lookup in the code above assumes that the character codes for the letters A to Z are contiguous. This is the case with all ASCII-based character sets (so all commonly used character sets), but is not the case with some exotic character sets that are still in use today, such as EBCDIC. For such character sets, a more complex array lookup is required.

However, based on your description of your program, instead of creating a stockChecker function, it would probably be more appropriate to create a function attemptpurchase which decrements the amount of stock, if possible, and then returns a value indicating whether the purchase was successful or not, and if not, the reason why the purchase failed. The function can also notify the caller function of the current stock status with an additional parameter. It would also be good if the function checked whether the product name is valid at all. Here is an example:

typedef enum
{
    PURCHASERESULTSUCCESS,
    PURCHASERESULTFAILUREINVALIDPRODUCTNAME,
    PURCHASERESULTFAILURESTOCKEMPTY

} purchaseresult;

purchase
result attemptpurchase( char productname, stockstatus *pss ) { // convert productname into array index, assuming ASCII-based character set // is being used int index = productname - 'A';

// determine whether product name is valid if ( index < 0 || index >= sizeof products / sizeof products[0] ) { *pss = STOCK
STATUSINVALID; return PURCHASERESULTFAILUREINVALIDPRODUCTNAME; }

// lookup the product in the products array product p = &products[index];

// check whether purchase is possible if ( p->amount == 0 ) {
pss = STOCKSTATUSEMPTY; return PURCHASERESULTFAILURESTOCKEMPTY; }

// perform purchase by decrementing the amount of stock p->amount--;

// set argument to indicate stock level if ( p->amount == 0 ) pss = STOCK_STATUS_EMPTY; else if ( p->amount > p->min ) pss = STOCKSTATUSABOVEMINIMUM; else if ( p->amount < p->min ) *pss = STOCKSTATUSBELOWMINIMUM; else pss = STOCK_STATUS_AT_MINIMUM;

// return value indicating that the purchase was successful return PURCHASE_RESULT_SUCCESS; }

Here is a demonstration program with full input validation:

#include 
#include 
#include 
#include 
#include 
#include 

typedef enum { STOCK_STATUS_INVALID, STOCK_STATUS_EMPTY, STOCK_STATUS_BELOW_MINIMUM, STOCK_STATUS_AT_MINIMUM, STOCK_STATUS_ABOVE_MINIMUM

} stock_status;

typedef enum { PURCHASE_RESULT_SUCCESS, PURCHASE_RESULT_FAILURE_INVALID_PRODUCT_NAME, PURCHASE_RESULT_FAILURE_STOCK_EMPTY

} purchase_result;

char get_char_from_user( char
prompt ); purchaseresult attemptpurchase( char productname, stockstatus pss );

typedef struct { int amount; int min;

} product;

product products[] = { { 12, 5 }, { 7, 3 }, { 9, 4 }, { 8, 4 } };

int main( void ) { printf ( "%s", "Welcome to my vending machine!\n" "You may enter the letter Q to quit.\n" "\n" );

for (;;) // infinite loop, equivalent to while(true) { stock_status ss;

// get input from user char c = get_char_from_user( "Please enter a product to purchase: " );

// if input is lower-case, make it upper-case c = toupper( (unsigned char)c );

// break out of loop if user wants to quit if ( c == 'Q' ) break;

// process purchase request switch ( attempt_purchase( c, &ss ) ) {

case PURCHASE_RESULT_SUCCESS: printf( "Purchase successful.\n" ); switch ( ss ) { case STOCK_STATUS_EMPTY: printf( "WARNING: Stock is now empty.\n" ); break; case STOCK_STATUS_BELOW_MINIMUM: printf( "WARNING: Stock level is below minimum.\n" ); break; case STOCK_STATUS_AT_MINIMUM: printf( "WARNING: Stock level is now at minimum.\n" ); break; case STOCK_STATUS_ABOVE_MINIMUM: // do nothing (there is no need to print a warning) break; default: assert( false ); } break;

case PURCHASE_RESULT_FAILURE_INVALID_PRODUCT_NAME: printf( "Purchase failed: Invalid product name!\n" ); break;

case PURCHASE_RESULT_FAILURE_STOCK_EMPTY: printf( "Purchase failed: Stock empty!\n" ); break;

default: assert( false ); } }

printf( "Quitting program.\n" ); }

purchase_result attempt_purchase( char product_name, stock_status
pss ) { // convert productname into array index, assuming ASCII-based character set // is being used int index = productname - 'A';

// determine whether product name is valid if ( index < 0 || index >= sizeof products / sizeof products[0] ) { pss = STOCK_STATUS_INVALID; return PURCHASE_RESULT_FAILURE_INVALID_PRODUCT_NAME; }

// lookup the product in the products array product
p = &products[index];

// check whether purchase is possible if ( p->amount == 0 ) { pss = STOCK_STATUS_EMPTY; return PURCHASE_RESULT_FAILURE_STOCK_EMPTY; }

// perform purchase by decrementing the amount of stock p->amount--;

// set argument to indicate stock level if ( p->amount == 0 )
pss = STOCKSTATUSEMPTY; else if ( p->amount > p->min ) pss = STOCK_STATUS_ABOVE_MINIMUM; else if ( p->amount < p->min ) pss = STOCKSTATUSBELOWMINIMUM; else *pss = STOCKSTATUSATMINIMUM;

// return value indicating that the purchase was successful return PURCHASERESULTSUCCESS; }

// NOTE: The following functions are only for user input, and are not part // of the main logic of the program.

// This function will read exactly one line of input from the // user. It will remove the newline character, if it exists. If // the line is too long to fit in the buffer, then the function // will automatically reprompt the user for input. On failure, // the function will never return, but will print an error // message and call "exit" instead. void getlinefromuser( const char *prompt, char *buffer, int buffersize ) { for (;;) //infinite loop, equivalent to while(1) { char p;

// prompt user for input fputs( prompt, stdout );

// explicitly flushing the output stream // may be necessary on some platforms fflush( stdout );

// attempt to read one line of input if ( fgets( buffer, buffer_size, stdin ) == NULL ) { printf( "Error reading from input!\n" ); exit( EXIT_FAILURE ); }

// attempt to find newline character p = strchr( buffer, '\n' );

// make sure that entire line was read in (i.e. that // the buffer was not too small to store the entire line) if ( p == NULL ) { int c;

// a missing newline character is ok if the next // character is a newline character or if we have // reached end-of-file (for example if the input is // being piped from a file or if the user enters // end-of-file in the terminal itself) if ( (c=getchar()) != '\n' && !feof(stdin) ) { if ( c == EOF ) { printf( "Error reading from input!\n" ); exit( EXIT_FAILURE ); }

printf( "Input was too long to fit in buffer!\n" );

// discard remainder of line do { c = getchar();

if ( c == EOF ) { // this error message will be printed if either // a stream error or an unexpected end-of-file // is encountered printf( "Error reading from input!\n" ); exit( EXIT_FAILURE ); }

} while ( c != '\n' );

// reprompt user for input by restarting loop continue; } } else { // remove newline character by overwriting it with // null character
p = '\0'; }

// input was ok, so break out of loop break; } }

char getcharfromuser( char *prompt ) { char line[100];

// repeat until input is valid for (;;) { get
linefromuser( prompt, line, sizeof line );

if ( line[0] != '\0' && line[1] == '\0' ) { return line[0]; }

printf( "Error: Please enter exactly one character!\n" ); } }

The code for the function getlinefromuser was taken from this answer of mine to another question.

This program has the following behavior:

Welcome to my vending machine!
You may enter the letter Q to quit.

Please enter a product to purchase: AZ Error: Please enter exactly one character! Please enter a product to purchase: Error: Please enter exactly one character! Please enter a product to purchase: ! Purchase failed: Invalid product name! Please enter a product to purchase: A Purchase successful. Please enter a product to purchase: B Purchase successful. Please enter a product to purchase: C Purchase successful. Please enter a product to purchase: D Purchase successful. Please enter a product to purchase: E Purchase failed: Invalid product name! Please enter a product to purchase: A Purchase successful. Please enter a product to purchase: A Purchase successful. Please enter a product to purchase: A Purchase successful. Please enter a product to purchase: A Purchase successful. Please enter a product to purchase: A Purchase successful. Please enter a product to purchase: A Purchase successful. WARNING: Stock level is now at minimum. Please enter a product to purchase: A Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: A Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: A Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: A Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: A Purchase successful. WARNING: Stock is now empty. Please enter a product to purchase: A Purchase failed: Stock empty! Please enter a product to purchase: A Purchase failed: Stock empty! Please enter a product to purchase: B Purchase successful. Please enter a product to purchase: B Purchase successful. Please enter a product to purchase: B Purchase successful. WARNING: Stock level is now at minimum. Please enter a product to purchase: B Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: B Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: B Purchase successful. WARNING: Stock is now empty. Please enter a product to purchase: B Purchase failed: Stock empty! Please enter a product to purchase: B Purchase failed: Stock empty! Please enter a product to purchase: Q Quitting program.

EDIT: Since you asked in the comments section how to make the program use strings instead of individual characters as the product names, I have now added a solution which does this:

#include 
#include 
#include 
#include 
#include 
#include 

typedef enum { STOCK
STATUSINVALID, STOCKSTATUSEMPTY, STOCKSTATUSBELOWMINIMUM, STOCKSTATUSATMINIMUM, STOCKSTATUSABOVEMINIMUM

} stockstatus;

typedef enum { PURCHASE
RESULTSUCCESS, PURCHASERESULTFAILUREINVALIDPRODUCTNAME, PURCHASERESULTFAILURESTOCKEMPTY

} purchaseresult;

void get
linefromuser( const char prompt, char buffer, int buffersize ); purchaseresult attemptpurchase( char *productname, stockstatus *pss );

typedef struct { char *name; int amount; int min;

} product;

product products[] = { { "apple", 12, 5 }, { "banana", 7, 3 }, { "cherry", 9, 4 }, { "dewberry", 8, 4 } };

int main( void ) { printf ( "%s", "Welcome to my vending machine!\n" "You may enter the letter Q to quit.\n" "\n" );

for (;;) // infinite loop, equivalent to while(true) { char input[200]; stock
status ss;

// get input from user getlinefromuser( "Please enter a product to purchase: ", input, sizeof input );

// make input lower-case for ( int i = 0; input[i] != '\0'; i++ ) { input[i] = tolower( (unsigned char)input[i] ); }

// break out of loop if user wants to quit if ( strcmp( input, "q" ) == 0 || strcmp( input, "quit" ) == 0 ) { break; }

// process purchase request switch ( attempt
purchase( input, &ss ) ) {

case PURCHASERESULTSUCCESS: printf( "Purchase successful.\n" ); switch ( ss ) { case STOCKSTATUSEMPTY: printf( "WARNING: Stock is now empty.\n" ); break; case STOCKSTATUSBELOWMINIMUM: printf( "WARNING: Stock level is below minimum.\n" ); break; case STOCKSTATUSATMINIMUM: printf( "WARNING: Stock level is now at minimum.\n" ); break; case STOCKSTATUSABOVEMINIMUM: // do nothing (there is no need to print a warning) break; default: assert( false ); } break;

case PURCHASE
RESULTFAILUREINVALIDPRODUCTNAME: printf( "Purchase failed: Invalid product name!\n" ); break;

case PURCHASERESULTFAILURESTOCKEMPTY: printf( "Purchase failed: Stock empty!\n" ); break;

default: assert( false ); } }

printf( "Quitting program.\n" ); }

purchaseresult attemptpurchase( char product_name, stock_status pss ) { // attempt to find product using linear search for ( int i = 0; i < sizeof products / sizeof products[0]; i++ ) { if ( strcmp( products[i].name, productname ) == 0 ) { // product was found, so now do further processing of the // purchase request

// check whether purchase is possible if ( products[i].amount == 0 ) { *pss = STOCK
STATUSEMPTY; return PURCHASERESULTFAILURESTOCKEMPTY; }

// perform purchase by decrementing the amount of stock products[i].amount--;

// set argument to indicate stock level if ( products[i].amount == 0 ) *pss = STOCK
STATUSEMPTY; else if ( products[i].amount > products[i].min ) *pss = STOCKSTATUSABOVEMINIMUM; else if ( products[i].amount < products[i].min ) pss = STOCK_STATUS_BELOW_MINIMUM; else pss = STOCKSTATUSATMINIMUM;

// return value indicating that the purchase was successful return PURCHASE
RESULTSUCCESS; } }

// indicate that product was not found *pss = STOCK
STATUSINVALID; return PURCHASERESULTFAILUREINVALIDPRODUCTNAME; }

// NOTE: The following function is only for user input, and are not part // of the main logic of the program.

// This function will read exactly one line of input from the // user. It will remove the newline character, if it exists. If // the line is too long to fit in the buffer, then the function // will automatically reprompt the user for input. On failure, // the function will never return, but will print an error // message and call "exit" instead. void getlinefromuser( const char *prompt, char *buffer, int buffersize ) { for (;;) //infinite loop, equivalent to while(1) { char p;

// prompt user for input fputs( prompt, stdout );

// explicitly flushing the output stream // may be necessary on some platforms fflush( stdout );

// attempt to read one line of input if ( fgets( buffer, buffer_size, stdin ) == NULL ) { printf( "Error reading from input!\n" ); exit( EXIT_FAILURE ); }

// attempt to find newline character p = strchr( buffer, '\n' );

// make sure that entire line was read in (i.e. that // the buffer was not too small to store the entire line) if ( p == NULL ) { int c;

// a missing newline character is ok if the next // character is a newline character or if we have // reached end-of-file (for example if the input is // being piped from a file or if the user enters // end-of-file in the terminal itself) if ( (c=getchar()) != '\n' && !feof(stdin) ) { if ( c == EOF ) { printf( "Error reading from input!\n" ); exit( EXIT_FAILURE ); }

printf( "Input was too long to fit in buffer!\n" );

// discard remainder of line do { c = getchar();

if ( c == EOF ) { // this error message will be printed if either // a stream error or an unexpected end-of-file // is encountered printf( "Error reading from input!\n" ); exit( EXIT_FAILURE ); }

} while ( c != '\n' );

// reprompt user for input by restarting loop continue; } } else { // remove newline character by overwriting it with // null character
p = '\0'; }

// input was ok, so break out of loop break; } }

This program uses linear search to find the product name in the products array. For this small array, linear search is sufficient. However, if your products array consists of hundreds or even thousands of elements, you will probably want to use a more efficient search algorithm, such as binary search or a hash table.

This program has the following behavior:

Welcome to my vending machine!
You may enter the letter Q to quit.

Please enter a product to purchase: AZ Purchase failed: Invalid product name! Please enter a product to purchase: Purchase failed: Invalid product name! Please enter a product to purchase: ! Purchase failed: Invalid product name! Please enter a product to purchase: Apple Purchase successful. Please enter a product to purchase: Banana Purchase successful. Please enter a product to purchase: Cherry Purchase successful. Please enter a product to purchase: Dewberry Purchase successful. Please enter a product to purchase: Elderberry Purchase failed: Invalid product name! Please enter a product to purchase: Apple Purchase successful. Please enter a product to purchase: Apple Juice Purchase failed: Invalid product name! Please enter a product to purchase: Apple Purchase successful. Please enter a product to purchase: Apple Purchase successful. Please enter a product to purchase: Apple Purchase successful. Please enter a product to purchase: Apple Purchase successful. Please enter a product to purchase: Apple Purchase successful. WARNING: Stock level is now at minimum. Please enter a product to purchase: Apple Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: Apple Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: Apple Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: Apple Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: Apple Purchase successful. WARNING: Stock is now empty. Please enter a product to purchase: Apple Purchase failed: Stock empty! Please enter a product to purchase: Apple Purchase failed: Stock empty! Please enter a product to purchase: Banana Purchase successful. Please enter a product to purchase: Banana Purchase successful. Please enter a product to purchase: Banana Purchase successful. WARNING: Stock level is now at minimum. Please enter a product to purchase: Banana Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: Banana Purchase successful. WARNING: Stock level is below minimum. Please enter a product to purchase: Banana Purchase successful. WARNING: Stock is now empty. Please enter a product to purchase: Banana Purchase failed: Stock empty! Please enter a product to purchase: Banana Purchase failed: Stock empty! Please enter a product to purchase: Q Quitting program.
October 5, 2025 Score: 8 Rep: 38,244 Quality: High Completeness: 80%

It sounds very much like you need:

  1. A struct definition to describe a product: a name, a current stock level, and a minimum stock level.
  2. An array of those to describe all of your products.
  3. A loop over those to find the one you're looking for and set a flag.
#define NAMELENGTH 20

typedef struct Product { char name[NAMELENGTH]; int stocklevel; int min; } Product;

int main(void) { Product products[] = { {"A", 42, 6}, {"B", 0, 1}, {"C", 3, 2} };

char inputproductname[NAMELENGTH];

if (fgets(inputproductname, NAMELENGTH, stdin) == NULL) { fprintf(stderr, "Input error.\n"); return 1; }

inputproductname[strcspn(inputproductname, "\n")] = 0;

int stockcheckerstate; bool found = false;

for (sizet i = 0; !found && i < sizeof(products) / sizeof(products[0]); i++) { if (strcmp(inputproductname, products[i].name)) { continue; }

found = true;

if (products[i].stocklevel > products[i].min) { stockcheckerstate = 3; } else if (products[i].stocklevel == products[i].min) { stockcheckerstate = 2; } else if (products[i].stocklevel != 0) { stockcheckerstate = 1; } else { stockcheckerstate = 0; } }

// Do something with found and stockchecker_state }

You should further remove the magic numbers from this and define an enum so that 0, 1, 2, and 3 are more meaningful.

A linear search of the array is acceptable for small arrays, but for larger ones you may wish to use an algorithm that scales better. For instance, a sorted array and a binary search.