24 fputs(
"1. Manage Stock Levels\n"
25 "2. Generate Reports\n"
26 "3. Quit the Program\n\n"
27 "Please enter your selection: ",
43 fputs(
"Invalid option.\n\n", stderr);
48 while ((ch = getchar()) !=
'\n' && ch != EOF)
55static size_t get_input_line(
char *
const buffer,
const size_t buffer_size, FILE *
const stream)
58 if (!fgets(buffer, buffer_size - 1, stream))
62 fputs(
"Could not get line of input: ", stderr);
63 fputs(strerror(errno), stderr);
67 const size_t input_length = strlen(buffer);
71 if (buffer[input_length - 1] !=
'\n') {
72 fputs(
"Could not get line of input: too long.\n", stderr);
76 buffer[input_length - 1] =
'\0';
84 const unsigned long value = strtoul(buffer, &end, 10);
86 if (errno != 0 || value >= UINT_MAX || *end !=
'\0') {
92 return (
unsigned int) value;
99 const long value = strtol(buffer, &end, 10);
101 if (errno != 0 || value <= INT_MIN || value >= INT_MAX || *end !=
'\0') {
115 int quantity_modifier;
118 fputs(
"Please Enter a Unique Product Number : ", stdout);
121 unsigned int product_id;
122 bool error_flag =
get_input_line(buffer,
sizeof(buffer) /
sizeof(buffer[0]), stdin) < 1;
128 fputs(
"That is not a valid product ID.\n", stderr);
134 fputs(
"A product with that number does not exist!\n", stderr);
143 fputs(
"Please Enter A Stock Level Adjustment Value : ", stdout);
146 bool error_flag =
get_input_line(buffer,
sizeof(buffer) /
sizeof(buffer[0]), stdin) < 1;
151 fputs(
"That is not a valid quantity modifier.\n", stderr);
158 fputs(
"There is insufficient stock to allow that.\n", stderr);
168 char path_buffer[PATH_MAX + 1];
170 fputs(
"Enter a destination filename for the report : ", stdout);
173 FILE *
const destination =
get_input_line(path_buffer,
sizeof(path_buffer) /
sizeof(path_buffer[0]), stdin)
174 ? fopen(path_buffer,
"w+")
178 fprintf(stderr,
"Error writing to report file: file error %d.\n", ferror(destination));
180 if (destination != stdout)
188 unsigned int product_id = 0;
190 while (
get_input_line(name_buffer,
sizeof(name_buffer) /
sizeof(name_buffer[0]), stock_file)) {
191 if (!
get_input_line(quantity_buffer,
sizeof(name_buffer) /
sizeof(name_buffer[0]), stock_file)) {
192 fprintf(stderr,
"Missing quantity for product \"%s\"\n", name_buffer);
200 fprintf(stderr,
"Quantity for product \"%s\" is invalid.\n", name_buffer);
205 if (new_product == NULL) {
206 fprintf(stderr,
"Could not create new product \"%s\": %s\n", name_buffer, strerror(errno));
212 fprintf(stderr,
"Could not create new product \"%s\": %s\n", name_buffer, strerror(errno));
223 FILE *
const fp = fopen(filename,
"r+");
227 fputs(
"could not open stock data file : ", stdout);
230 fputs(strerror(errno), stdout);
231 fputs(
" : ", stdout);
235 fputs(
"using stock data file : ", stdout);
246 fprintf(stderr,
"Error writing to stock data file: file error %d.\n", ferror(datafile));
249int main(
const int argc,
const char **
const argv)
251 fputs(
"Stock Control Program Started - ", stdout);
252 FILE *stock_file =
open_stock_file(argc > 1 ? argv[1] :
"stock_data.txt");
253 if (stock_file == NULL)
263 bool continue_running =
true;
264 while (continue_running) {
274 continue_running =
false;
int pool_serialise_report(const struct Pool *const this, FILE *const buffer)
bool pool_insert_element(struct Pool *const this, struct Product *const product)
struct Product * pool_get_product_by_index(const struct Pool *const this, const unsigned int index)
void pool_delete(struct Pool **const this)
struct Pool * pool_create(const unsigned int initial_capacity, const float growth_factor)
int pool_serialise_stock_file(const struct Pool *const this, FILE *const buffer)
Pool class specification.
struct Product * product_create(const unsigned int id, const char *const name, const unsigned int quantity)
void product_delete(struct Product **this)
bool product_modify_quantity(struct Product *this, const int modifier)
Product class specification.
#define MAX_NAME_LENGTH
Maximum number of bytes for a Product name, excluding the NULL-terminator.
static void save_inventory(FILE *const datafile, const struct Pool *const pool)
static FILE * open_stock_file(const char *const filename)
static void manage_stock(const struct Pool *const pool)
static int load_inventory(FILE *const stock_file, struct Pool *const pool)
static void generate_reports(const struct Pool *const pool)
static enum MenuOption get_menu_selection()
static unsigned int convert_to_uint(const char *const buffer, bool *error)
int main(const int argc, const char **const argv)
static size_t get_input_line(char *const buffer, const size_t buffer_size, FILE *const stream)
static int convert_to_sint(const char *const buffer, bool *error)
An ordered expandable collection of dynamically allocated Product records.
The Product represents a single product with a unique numerical identifier, human-readable name,...
unsigned int quantity
Non-negative number of Product items in stock.