4. Текст програми з коментарями
// Katerina Leschenko, IS-12, FICT
//
// Create an array of structures. Each structure consists of data about a consumer or a product.
// Each consumer has his/her profit. Each product has a price and a level of usefulness (utility)
// (an arbitrary function). The created array must be written to a binary file. There must be
// an opportunity to add new data, to change data in the file, delete data from the file.
// Implement queries by determining: 1) products with particular utility that consumers with particular
// income can afford, 2) the integrated cost of the products with the highest utility, and 3) consumers
// whose income is not enough to buy products with particular price and utility.
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <share.h>
using namespace std;
FILE* myfile; // the pointer to a data file
char NAME[25]; // the name of the file
string NAME1; // the real name of the file
bool flagg; // whether the data has been removed by the appropriate function
struct Prod // product structure
{
float price;
int utility;
};
struct Cons // consumer structure
{
float income;
};
struct Something // product or consumer
{
char name[25];
bool tag; // 0 - product, 1 - consumer
union
{
Prod product;
Cons consumer;
};
};
Something smth; // a product or a consumer
void WriteData1(); // function for writing data to a new file
void Writing(); // function for writing data
void ViewData(); // function for viewing a file
void AddData(); // function for adding new consumer/consumers/product/products to a file
void AddProd(char* answer); // function to add a product (products)
void AddCons(char* answer); // function to add a consumer (consumers)
void EmptyFile(); // function for cleaning a file
void ChangeData(); // function for changing all the data in a file
void ChangePartData(); // function for changing data about 1 consumer/product
void FindProd(); // function for finding products with particular utility that consumers with particular income can afford
void IntCost(); // function for finding the integrated cost of the products with the highest utility
void FindCons(); // function for finding consumers whose income is not enough to buy products with particular price and utility
void RemCons(); // function for removing 1 consumer/product
void Reading(); // function for opening a new existing file to work with
bool OpenForRead(); // function for opening a file for reading
void ClearName(string& str); // function for removing ' ' from the left and from the right in a file's name
void main()
{
cout << "Program 'LAB 1' made by Katerina Leschenko," << endl;
cout << "FICT, NTUU 'KPI', IS-12" << endl << endl;
cout << "This is a program that is designed to solve this problem:" << endl;
cout << "Create an array of structures. Each structure consists of data about" << endl;
cout << "a consumer or a product. Each consumer has his/her profit. Each product has" << endl;
cout << "a price and a level of usefulness (utility) (an arbitrary function)." << endl;
cout << "The created array must be written to a binary file. There must be an oppor-" << endl;
cout << "tunity to add new data, to change data in the file, delete data from the file." << endl;
cout << "Implement queries by determining:" << endl;
cout << "1) products with particular utility that consumers with particular income" << endl;
cout << " can afford," << endl;
cout << "2) the integrated cost of the products with the highest utility," << endl;
cout << "3) consumers whose income is not enough to buy products with particular" << endl;
cout << " price and utility." << endl; // output the greating and the conditions of the problem
getch(); // waiting for pressing any key
while(1)
{
system("cls"); // clear the screen
cout << " MENU:" << endl;
cout << "1. Input data and write it to a file." << endl;
cout << "2. Open an existing file." << endl;
cout << "3. View the data." << endl;
cout << "4. Add data to the file (add consumers/products)." << endl;
cout << "5. Remove one consumer/product." << endl;
cout << "6. Empty the file." << endl;
cout << "7. Change all the data in the file." << endl;
cout << "8. Change the data about one consumer/product." << endl;
cout << "9. Find products with particular utility that consumers" << endl;
cout << " with particular income can afford." << endl;
cout << "10. Find the integrated cost of the products" <<endl;
cout << " with the highest utility." <<endl;
cout << "11. Find consumers whose income is not enough" <<endl;
cout << " to buy products with particular price and utility." <<endl;
cout << "12. Exit." << endl; // output the menu
short key; // the variable for choosing a menu item
cout << endl << "The choosen menu item: ";
cin >> key; // input key
switch (key)
{
case 1 : {WriteData1(); break;}
case 2 : {Reading(); break;}
case 3 : {ViewData(); break;}
case 4 : {AddData(); break;}
case 5 : {RemCons(); break;}
case 6 : {EmptyFile(); break;}
case 7 : {ChangeData(); break;}
case 8 : {ChangePartData(); break;}
case 9 : {FindProd(); break;}
case 10 : {IntCost(); break;}
case 11 : {FindCons(); break;}
case 12 : {exit(0);} // exit
default : {cout << "Such item does not exist. Try again." << endl; getch();} // output a message
} // make a choice according to the key
}
}
//======= function for removing ' ' from the left and from the right =======
//============================ in a file's name ============================
void ClearName(string& str)
{
str.erase(0, str.find_first_not_of(' ')); // erase ' ' from the left
str.erase(str.find_last_not_of(' ') + 1); // erase ' ' from the right
}
//================ function for opening a file for reading ================
bool OpenForRead()
{
myfile = fopen(NAME1.c_str(), "rb"); // open the file in the reading mode
if (!myfile) // if the opening wasn't successful
{
cerr << "File does not exist!" << endl;
getch();
return false;
}
return true; // if everything's all right
}
//======================= function for writing data =======================
void Writing()
{
char answer[10]; // whether there are more consumers/products
do
{
cout << "Consumer's name:" << endl;
fflush(stdin); // clear the keyboard buffer
gets(smth.name);
smth.tag = 1;
cout << "Consumer's income:" << endl;
cin >> smth.consumer.income; // input data about a consumer
cout << "More consumers? [yes/no]" << endl;
fflush(stdin);
gets(answer);
fwrite(&smth, sizeof(Something), 1, myfile);
} while(strcmpi(answer, "no"));
do
{
cout << "Product's name:" << endl;
fflush(stdin); // clear the keyboard buffer
gets(smth.name);
smth.tag = 0;
cout << "Product's price:" << endl;
cin >> smth.product.price; // input data about a product
smth.product.utility = int(smth.product.price/3) + strlen(smth.name); // find its utility
cout << "More products? [yes/no]" << endl;
fflush(stdin);
gets(answer);
fwrite(&smth, sizeof(Something), 1, myfile);
} while(strcmpi(answer, "no"));
flagg = false; // there is data in the file
}
//================ function for writing data to a new file ================
void WriteData1()
{
cout << "Enter the name of the file you want to create:" << endl;
fflush(stdin);
gets(NAME); // input the name of a file
NAME1 = NAME; // create a copy of the file's name
ClearName(NAME1); // remove ' ' from the left and from the right
while (NAME1.empty()) // if the file's name is empty
{
cout << "Such name is wrong! Try again:" << endl;
fflush(stdin);
gets(NAME); // input the name of a file
NAME1 = NAME; // create a copy of the file's name
ClearName(NAME1); // remove ' ' from the left and from the right
}
myfile = fopen(NAME1.c_str(), "wb"); // open this file
Writing(); // write data to the file
fclose(myfile); // close the file
}
//====================== function for viewing a file ======================
void ViewData()
{
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
if (flagg) cout << "There is no data in this file." << endl; // if there is no data in the file
else
{
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile))
{
if (smth.tag == 0)
{
cout << "Product " << smth.name << ":" << endl;
cout << " price: " << smth.product.price << " UAH" << endl;
cout << " utility: " << smth.product.utility << endl << endl;
}
else
{
cout << "Consumer " << smth.name << ":" << endl;
cout << " income: " << smth.consumer.income << " UAH" << endl << endl;
}
fread(&smth, sizeof(Something), 1, myfile);
}
}
fclose(myfile); // close the file
getch();
}
}
//=================== function to add a product (products) ===================
void AddProd(char* answer)
{
do
{
cout << "Product's name:" << endl;
fflush(stdin); // clear the keyboard buffer
gets(smth.name);
smth.tag = 0; // it is a product
cout << "Product's price:" << endl;
cin >> smth.product.price; // input data about a product
smth.product.utility = int(smth.product.price/3) + strlen(smth.name); // find its utility
cout << "More products? [yes/no]" << endl;
fflush(stdin);
gets(answer);
fwrite(&smth, sizeof(Something), 1, myfile);
} while(strcmpi(answer, "no"));
}
//================== function to add a consumer (consumers) ===================
void AddCons(char* answer)
{
do
{
cout << "Consumer's name:" << endl;
fflush(stdin); // clear the keyboard buffer
gets(smth.name);
smth.tag = 1; // it is a consumer
cout << "Consumer's income:" << endl;
cin >> smth.consumer.income; // input data about a consumer
cout << "More consumers? [yes/no]" << endl;
fflush(stdin);
gets(answer);
fwrite(&smth, sizeof(Something), 1, myfile);
} while(strcmpi(answer, "no"));
}
//== function for adding new consumer/consumers/product(-s) to a file ==
void AddData()
{
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
fclose(myfile); // close the file
myfile = fopen(NAME1.c_str(), "ab"); // open in the "ab" mode
char answer[10]; // whether there are more consumers/products
cout << "What do you want to add? [prod/cons]" << endl;
fflush(stdin);
gets(answer);
if (!strcmpi("prod", answer))
{
AddProd(answer); // add a product/products
cout << "Do you want to add consumers too? [yes/no]" << endl;
fflush(stdin);
gets(answer);
if (!strcmpi(answer, "yes")) // if yes
{
flagg = false; // there is data in the file
AddCons(answer); // add a consumer/consumers
}
}
else
{
AddCons(answer); // add a consumer/consumers
cout << "Do you want to add products too? [yes/no]" << endl;
fflush(stdin);
gets(answer);
if (!strcmpi(answer, "yes")) // if yes
{
flagg = false; // there is data in the file
AddProd(answer); // add a product/products
}
}
fclose(myfile); // close the file
}
}
//============== function for removing 1 consumer/product ===============
void RemCons()
{
char c_name[20]; // the name of a consumer/product
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
if (flagg) // if there is no data in this file
{
cout << "There is no data in this file." << endl;
fclose(myfile);
}
else
{
fclose(myfile);
myfile = fopen(NAME1.c_str(), "r+b");
cout << "Enter the name of the consumer/product whose data you want to remove." << endl;
fflush(stdin);
gets(c_name); // input the name
bool flag0 = false; // whether there is such a consumer/product
int i = 0;
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile) && strcmp(smth.name, c_name))
{
fread(&smth, sizeof(Something), 1, myfile);
i++;
} // read the data and work with it
if (!strcmp(smth.name, c_name)) // if the name if the same
flag0 = true; // there is such a consumer/product
fpos_t pos;
int j = 0;
while (!feof(myfile))
{
if (fread(&smth, sizeof(Something), 1, myfile) != NULL)
{
fgetpos(myfile, &pos); // get the current position
fseek(myfile, (i + j)*sizeof(Something), SEEK_SET); // two structures to the left
fwrite(&smth, sizeof(Something), 1, myfile); // paste the structure that was read here
fsetpos(myfile, &pos);
j++;
}
}
fclose(myfile);
int pfh;
_sopen_s(&pfh, NAME1.c_str(), _O_RDWR, _SH_DENYNO, _S_IREAD | _S_IWRITE); // open the file
int size = _filelength(pfh); // the old size of the file
_chsize(pfh, size - sizeof(Something)); // cut the last structure
_close(pfh); // close the file
if (!flag0) cout << "No consumers/products found." << endl; // if there are no consumers we're looking for
else cout << "The data has been removed successfully." << endl;
}
getch();
}
}
//====================== function for cleaning a file ======================
void EmptyFile()
{
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
fclose(myfile); // close it
if (flagg) cout << "There is already no data in this file." << endl; // if there is already no data
else
{
myfile = fopen(NAME1.c_str(), "wb"); // open the file in the writing mode
fclose(myfile); // close it
flagg = true; // there is no data in the file
cout << "The file is now empty." << endl;
}
getch();
}
}
//============== function for changing all the data in a file ==============
void ChangeData()
{
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
fclose(myfile); // close it
myfile = fopen(NAME1.c_str(), "wb"); // open in the writing mode
Writing(); // write data
fclose(myfile); // close the file
}
}
//============ function for changing data about 1 consumer/product ============
void ChangePartData()
{
bool flag3 = false; // whether there are such consumers/products
char c_p_name[20]; // the name of a consumer
char answer[10]; // whether there are more consumers/products to add, what to add
if (!(myfile = fopen(NAME1.c_str(), "r+b"))) // if the file wasn't successfully opened in the "r+b" mode
{
cerr << "File does not exist!" << endl;
getch();
}
else
{
if (flagg) cout << "There is no data in this file." << endl; // if there is no data in the file
else
{
cout << "Enter the name of the consumer/product whose data you want to change:" << endl;
fflush(stdin);
gets(c_p_name); // input the consumer's/product's name
int i = 0;
fread(&smth, sizeof(Something), 1, myfile); // read the data
while (!feof(myfile) && strcmp(c_p_name, smth.name))
{
fread(&smth, sizeof(Something), 1, myfile); // read the data
i++;
}
if (!strcmp(c_p_name, smth.name)) // if the name is the same
flag3 = true; // there is such a consumer/product
if (flag3)
{
cout << "What do you want it to be? [prod/cons]" << endl;
fflush(stdin);
gets(answer);
if (!strcmpi(answer, "prod"))
{
cout << "Product's name:" << endl;
fflush(stdin); // clear the keyboard buffer
gets(smth.name);
smth.tag = 0;
cout << "Product's price:" << endl;
cin >> smth.product.price; // input data about a product
smth.product.utility = int(smth.product.price/3) + strlen(smth.name); // find its utility
}
else
{
cout << "Consumer's name:" << endl;
fflush(stdin); // clear the keyboard buffer
gets(smth.name);
smth.tag = 1;
cout << "Consumer's income:" << endl;
cin >> smth.consumer.income; // input data about a consumer
}
fseek(myfile, i*sizeof(Something), SEEK_SET); // move to the beginning of the structure we want to change
fwrite(&smth, sizeof(Something), 1, myfile);
cout << endl << "The data has been changed successfully." << endl; // if we have changed the data
}
else
{
cout << "No products/consumers found." << endl;
}
}
fclose(myfile); // close the file
getch();
}
}
//========= function for opening a new existing file to work with =========
void Reading()
{
cout << "Enter the name of the file you want to open:" << endl;
fflush(stdin);
gets(NAME); // input the name of the file
NAME1 = NAME; // create a copy of the file's name
ClearName(NAME1); // remove ' ' from the left and from the right
while (NAME1.empty()) // if the file's name is empty
{
cout << "Such name is wrong! Try again:" << endl;
fflush(stdin);
gets(NAME); // input the name of a file
NAME1 = NAME; // create a copy of the file's name
ClearName(NAME1); // remove ' ' from the left and from the right
}
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
cout << "The file has been opened successfully." << endl;
fclose(myfile); // close the file
getch();
flagg = false; // there is data in the file
}
}
//========= function for finding products with particular utility =========
//============ that consumers with particular income can afford ============
void FindProd()
{
bool flag = false; // whether there are such consumers
int u; // the utility we're interested in
float inc; // the income we're interested in
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
if (flagg) cout << "There is no data in this file." << endl; // of there is no data in the file
else
{
cout << "Enter the income and utility you're interested in:" << endl;
cin >> inc >> u; // input the income and utility we're interested in
fpos_t pos;
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile))
{
if ((smth.tag == 1) && (inc == smth.consumer.income)) // if the income is the same
{
flag = true; // there is such a consumer
printf("%s can afford such products with the utility %d:\n", smth.name, u);
bool flag1 = false; // whether there are such products
fgetpos(myfile, &pos);
fseek(myfile, 0, SEEK_SET); // find the beginning of the file
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile))
{
if ((smth.tag == 0) && (u == smth.product.utility) && (inc >= smth.product.price)) // if this is a product we're looking for
{
flag1 = true; // there is such a product
printf("- %s\n", smth.name); // output the name of this product
}
fread(&smth, sizeof(Something), 1, myfile);
}
if (!flag1) cout << "no products" << endl; // if there are no such products
fsetpos(myfile, &pos);
}
fread(&smth, sizeof(Something), 1, myfile);
} // read the data and work with it
if (!flag) cout << "There are no consumers with such an income." << endl; // if there are no such consumers (but if there is data in the file)
}
fclose(myfile); // close the file
getch();
}
}
//======== function for finding the integrated cost of the products ========
//======================== with the highest utility ========================
void IntCost()
{
int max_u = 0; // the maximum product utility
float sum = 0; // the integrated cost
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
if (flagg) cout << "There is no data in this file." << endl; // if there is no data in the file
else
{
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile))
{
if ((smth.tag == 0) && (max_u < smth.product.utility))
{
max_u = smth.product.utility;
}
fread(&smth, sizeof(Something), 1, myfile);
} // read the data and find the max utility
fseek(myfile, 0, SEEK_SET); // go to the beginning of the file
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile))
{
if ((smth.tag == 0) && (max_u == smth.product.utility))
{
sum += smth.product.price;
}
fread(&smth, sizeof(Something), 1, myfile);
} // read the data and find the maximum utility
cout << "The integrated cost is " << sum << " UAH." << endl; // output the results
}
fclose(myfile); // close the file
getch();
}
}
//======= function for finding consumers whose income is not enough =======
//=========== to buy products with particular price and utility ===========
void FindCons()
{
float pr; // the price we're interested in
int ut; // the utility we're interested in
float stoim = 0; // the cost of all the suitable products
if (OpenForRead() == true) // if the file was successfully opened in the reading mode
{
if (flagg) cout << "There is no data in this file." << endl; // if there is no data in the file
else
{
cout << "Enter the price and utility you're interested in:" << endl;
cin >> pr >> ut;
cout << "Consumers whose income is not enough:" << endl;
bool flag2 = false; // whether there are such consumers
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile))
{
if ((smth.tag == 0) && (ut == smth.product.utility) && (pr == smth.product.price))
{
stoim += pr;
}
fread(&smth, sizeof(Something), 1, myfile);
} // read the data and find stoim
fseek(myfile, 0, SEEK_SET); // go to the beginning of the file
fread(&smth, sizeof(Something), 1, myfile);
while (!feof(myfile))
{
if ((smth.tag == 1) && (smth.consumer.income < stoim))
{
flag2 = true;
printf("- %s\n", smth.name);
}
fread(&smth, sizeof(Something), 1, myfile);
} // read the data and find consumers whose income is not enough
if (!flag2) cout << "no consumers" << endl; // if there are no such consumers
}
fclose(myfile); // close the file
getch();
}
}