问题
Hey guys i am doing a project at school and i need to fill an array of pointers with info from a text doc:
4101 BRAEBURN_REG 1 0.99 101.5
4021 DELICIOUS_GDN_REG 1 0.89 94.2
4020 DELICIOUS_GLDN_LG 1 1.09 84.2
4015 DELICIOUS_RED_REG 1 1.19 75.3
4016 DELICIOUS_RED_LG 1 1.29 45.6
4167 DELICIOUS_RED_SM 1 0.89 35.4
4124 EMPIRE 1 1.14 145.2
4129 FUJI_REG 1 1.05 154.5
4131 FUJI_X-LGE 1 1.25 164.1
4135 GALA_LGE 1 1.35 187.7
4133 GALA_REG 1 1.45 145.2
4139 GRANNY_SMITH_REG 1 1.39 198.2
4017 GRANNY_SMITH_LGE 1 1.49 176.5
3115 PEACHES 1 2.09 145.5
4011 BANANAS 1 0.49 123.2
4383 MINNEOLAS 1 0.79 187.3
3144 TANGERINES 1 1.19 135.5
4028 STRAWBERRIES_PINT 0 0.99 104
4252 STRAWBERRIES_HALF_CASE 0 3.99 53
4249 STRAWBERRIES_FULL_CASE 0 7.49 67
94011 ORGANIC_BANANAS 1 0.99 56.3
So i have to take that a put it in to a struct. Here is my function doing so:
bool readInventory(string filename)
{
inputFile.open(filename); //opening products file
bool errors = true;
if(!inputFile.fail()) // validate that the file did open
{
while (!filename) // Dynamically creates array and fills with info
{
product *inventory = new product();
inputFile >> inventory->plu;
inputFile >> inventory->itemName;
inputFile >> inventory->saleType;
inputFile >> inventory->price;
inputFile >> inventory->currentInventory;
itemArray[counter] = inventory;
counter++;
cout << itemArray[14]<< endl;
}
}
else
{
cout << "\nError, unable to open products.txt.\n";
errors = false;
return errors;
}
}// ends readInventory
It wont fill in the array, but if i do while (filename) // Dynamically creates array and fills with info
it will record the first item into the array only, leaving the others blank. I also need to validate the input. (i.e the PLU code is not an integer, the plu type is string though) and skip product with problems and change the bool errors
from true to false. Here is my whole code:
#include <iostream>
#include <string>
#include <fstream>
#include <cctype>
using namespace std;
bool readInventory(string filename);
double checkout();
bool updateInventory(string filename);
// prototypes
int counter = 0; //used to fill the array
ifstream inputFile; //file to read from
const int SIZES = 100; //constant int used to tell sizes
product *itemArray[SIZES]; //array of pointers of size 100
struct product
{
string plu; //price look up code for each product
string itemName; //name of item
int saleType; //item is per pound or per unit
int price; //price of item
int currentInventory; //amount in stock
};
int main ()
{
int choice; // choice is used to find out what choice they want in the menu.
bool menuOn = true; //menuOn is used to turn on and off the menu.
readInventory("Products.txt");
while (menuOn == true)
{
cout << "1 - Check out.\n";
cout << "2 - Close the store and exit.\n";
cout << "Enter your choice and press return: ";
//Displays choices for the menu
cin >> choice; //Chose what menu option you want
cout << endl;
switch (choice)
{
case 1:
checkout();
break;
case 2:
cout << "Thank you for using this item check out program.";
menuOn = false;
break;
default:
cout << "Not a Valid Choice. \n";
cout << "Choose again.\n\n";
break;
// Safty net if user doent enter choice 1-2
}
}
inputFile.close();
cout << endl;
system("pause");
return 0;
} // end function main ()
bool readInventory(string filename)
{
inputFile.open(filename); //opening products file
bool errors = true;
if(!inputFile.fail()) // validate that the file did open
{
while (counter < 22) // Dynamically creates array and fills with info
{
product *inventory = new product();
inputFile >> inventory->plu;
inputFile >> inventory->itemName;
inputFile >> inventory->saleType;
inputFile >> inventory->price;
inputFile >> inventory->currentInventory;
itemArray[counter] = inventory;
counter++;
}
}
else
{
cout << "\nError, unable to open products.txt.\n";
errors = false;
return errors;
}
}// ends readInventory
double checkout()
{
double total = 0; //total cost
string pluCode; // code to look for
bool found = false; // notify if item is found
double costs;
double quantity;
bool codeValid = true;
do
{
cout << "Please enter PLU code or 0 to exit: ";
codeValid = true;
cin >> pluCode;
/* for (int x = 0; x <= pluCode.length(); x++)
{
if ((pluCode[x] != '1') && (pluCode[x] != '2') && (pluCode[x] != '3') && (pluCode[x] != '4') && (pluCode[x] != '5') && (pluCode[x] != '6') && (pluCode[x] != '7') && (pluCode[x] != '8') && (pluCode[x] != '9') && (pluCode[x] != '0'))
{
codeValid = false;
}
} */
for (int itemFind = 0 ; itemFind < counter; itemFind++)
{
if (itemArray[itemFind]->plu == pluCode)
{
found = true;
costs = itemArray[itemFind]->price;
cout << "Please enter lbs or quantity: ";
cin >> quantity;
if (costs); // Data Validation
costs = quantity*costs;
total += costs;
};
};
if(!found)
{
cout << "Please enter a valid PLU code.\n";
}
} while (pluCode != "0");
if (total > 50.00)
total = (.95*total);
return total;
return 0.00;
}//ends Checkout
bool updateInventory(string filename)
{
return true;
}//ends updateInventory
Here is a link to the actual assignment if anyone needs it: https://www.dropbox.com/s/howsf5af2gsa1i8/CS1Asg4BStructures.docx
回答1:
To read all the lines from the file use the following code:
std::string line;
while (std::getline(inputFile,line))
{
std::istringstream iss(line);
product *inventory = new product();
iss >> inventory->plu;
iss >> inventory->itemName;
iss >> inventory->saleType;
iss >> inventory->price;
iss >> inventory->currentInventory;
itemArray[counter] = inventory;
++counter;
}
Also try to get rid of the global variable definitions (e.g. counter
, inputFile
) and provide them as function local variables or parameters (or in case for counter
it could be even reasonable to use it as return value: return 0
or -1
for error cases, and the number of records read otherwise). Also you'll need to check that counter
is less than SIZES
before allocating a new record and assign it to itemArray[counter]
.
I would recommend at least using a std::vector
to manage the records:
std::vector<product> itemArray;
// ...
std::string line;
while (std::getline(inputFile,line))
{
std::istringstream iss(line);
product newProd;
iss >> newProd.plu;
iss >> newProd.itemName;
iss >> newProd.saleType;
iss >> newProd.price;
iss >> newProd.currentInventory;
itemArray.push_back(newProd);
}
No need for counter
with this code, itemArray.size()
will tell about the number of records read from the file.
回答2:
I suspect you meant
while (inputFile)
instead of
while (!filename)
回答3:
!filename
makes no sense, you are negating a string. If you know how many items there will be you can make a condition such as while (counter < (howManyItems))
. If you don't you can go through a loop finding end of line characters first and then change the while to a for.
来源:https://stackoverflow.com/questions/22518465/filling-structure-from-a-file