First things first, I'm relatively new to C++. I'm just finishing up my first semester of computer science and I'm getting the error "Segmentation Fault (core dumped)" while opening a file in my final. I believe the error has to do with pointers and occurs somewhere in the
while(!file.eof())
{
Item temp;
int readsize = 0;
file >> readsize;
if(readsize)
{
file.read((char*)&temp.itemDescription, readsize);
file >> temp.dateAdded;
file >> temp.quantity;
file >> temp.retailCost;
file >> temp.wholesaleCost;
inventory.push_back(temp);
std::cout << "\t\tRead item " << temp.itemDescription << std::endl;
}
}
portion of my program. Any help would be much appreciated.
My program is as follows:
#include <iostream>
#include <string.h>
#include <sstream>
#include <fstream>
#include <vector>
struct Item {
std::string itemDescription;
int quantity;
float wholesaleCost, retailCost;
std::string dateAdded;
};
int displayMenu();
void pressEnterToContinue();
Item newItem();
void readInventory(std::string, std::vector<Item>&);
void saveInventory(std::string, std::vector<Item>);
void displayRecords(std::vector<Item>);
void outputItem(Item);
int main (int argc, const char * argv[])
{
std::vector<Item> inventory;
int userSelection;
std::string fileName;
readInventory("inventory.dat", inventory);
do {
userSelection = displayMenu();
switch (userSelection)
{
case 1:
{
inventory.push_back(newItem());
break;
}
case 2:
{
unsigned int menuIndex;
do {
displayRecords(inventory);
std::cout << "Enter the number of the record to view: ";
std::cin >> menuIndex;
if (menuIndex < 0 || menuIndex >= inventory.size())
std::cout << "Invalid input!" << std::endl;
} while (menuIndex < 0 || menuIndex >= inventory.size());
outputItem(inventory[menuIndex]);
pressEnterToContinue();
break;
}
case 3:
{
unsigned int menuIndex;
do {
displayRecords(inventory);
std::cout << "Enter the number of the record to change: ";
std::cin >> menuIndex;
if (menuIndex < 0 || menuIndex >= inventory.size())
std::cout << "Invalid input!" << std::endl;
} while (menuIndex < 0 || menuIndex >= inventory.size());
inventory[menuIndex] = newItem();
break;
}
case 4:
{
saveInventory("inventory.dat", inventory);
std::cout << "Bye!" << std::endl;
break;
}
}
} while (userSelection != 4);
return 0;
}
Item newItem()
{
Item temp;
std::cout << "Item description: ";
std::cin.ignore();
getline (std::cin,temp.itemDescription);
// Asks user for the quantity and checks if it is negative.
while (true)
{
std::cout << "Quantity: ";
std::cin >> temp.quantity;
if (temp.quantity > 0)
break;
else
{
std::cout << "Please enter a number greater than zero." << std::endl;
pressEnterToContinue();
std::cout << std::endl;
}
}
// Asks user for wholesale cost and checks if it is negative.
while (true)
{
std::cout << "Wholesale Cost: $";
std::cin >> temp.wholesaleCost;
if (temp.wholesaleCost >= 0)
break;
else
{
std::cout << "Please enter a number equal to or greater than zero." << std::endl;
pressEnterToContinue();
std::cout << std::endl;
}
}
// Asks user for retail cost and checks if it is negative.
while (true)
{
std::cout << "Retail Cost: $";
std::cin >> temp.retailCost;
if (temp.retailCost >= 0)
break;
else
{
std::cout << "Please enter a number equal to or greater than zero." << std::endl;
pressEnterToContinue();
std::cout << std::endl;
}
}
// Asks user for the date and checks if it is valid.
while (true)
{
int month, day, year;
bool allClear = 0;
std::cout << "Please enter the date seperated by spaces (mm dd yy ex. 02 09 98 for February 9th, 1998): ";
std::cin >> month >> day >> year;
if (month > 12 || month < 1)
{
std::cout << "Please enter a valid month." << std::endl;
pressEnterToContinue();
}
else
{
if ((month == 1 && (day > 31 || day < 1)) || (month == 2 && (day > 29 || day < 1)) || (month == 3 && (day > 31 || day < 1)) || (month == 4 && (day > 30 || day < 1)) || (month == 5 && (day > 31 || day < 1)) || (month == 6 && (day > 30 || day < 1)) || (month == 7 && (day > 31 || day < 1)) || (month == 8 && (day > 31 || day < 1)) || (month == 9 && (day > 30 || day < 1)) || (month == 10 && (day > 31 || day < 1)) || (month == 11 && (day > 30 || day < 1)) || (month == 12 && (day > 31 || day < 1)))
{
std::cout << "Please enter a valid day." << std::endl;
pressEnterToContinue();
}
else
{
if (year < 0)
{
std::cout << "Please enter a positive year." << std::endl;
pressEnterToContinue();
}
else
allClear = 1;
}
}
if (allClear == 1)
{
std::stringstream ss;
break;
}
}
return temp;
}
void pressEnterToContinue()
{
std::cin.sync();
std::cout << "Please press enter to continue..." << std::endl;
std::cin.get();
}
int displayMenu()
{
int userSelection;
do {
std::cout << "====================" << std::endl;
std::cout << " MAIN MENU " << std::endl;
std::cout << "====================" << std::endl;
std::cout << std::endl;
std::cout << "[1] Add a new record" << std::endl;
std::cout << "[2] View existing records" << std::endl;
std::cout << "[3] Modify an existing record" << std::endl;
std::cout << "[4] Save and exit" << std::endl;
std::cout << "Your selection: ";
std::cin >> userSelection;
if (userSelection < 1 || userSelection > 4)
std::cout << "Invalid input!" << std::endl;
} while (userSelection < 1 || userSelection > 4);
return userSelection;
}
void displayRecords(std::vector<Item> inventory)
{
std::cout << "Records:" << std::endl;
for (unsigned int i = 0; i < inventory.size(); i++)
std::cout << i << " - " << inventory[i].itemDescription << std::endl;
}
void outputItem(Item output)
{
std::cout << std::endl;
std::cout << "Description: " << output.itemDescription << std::endl;
std::cout << "Quantity: " << output.quantity << std::endl;
std::cout << "Wholesale Cost: " << output.wholesaleCost << std::endl;
std::cout << "Retail: " << output.retailCost << std::endl << std::endl;
}
void saveInventory(std::string fileName, std::vector<Item> inventory)
{
std::cout << "\tOpening " << fileName << std::endl;
std::fstream file(fileName.c_str(), std::ios::out);
if (file.good())
{
std::cout << "\t\tSuccessfully opened file" << std::endl;
for (unsigned int i = 0; i < inventory.size(); i++)
{
file << sizeof(inventory[i].itemDescription);
file.write((char*)&inventory[i].itemDescription, sizeof(inventory[i].itemDescription));
file << inventory[i].dateAdded << std::endl;
file << inventory[i].quantity << std::endl;
file << inventory[i].retailCost << std::endl;
file << inventory[i].wholesaleCost << std::endl;
std::cout << "\t\tWrote item: " << inventory[i].itemDescription << std::endl;
}
}
else
std::cout << "\t\tFailure opening file" << std::endl;
file.close();
std::cout << "\tClosed " << fileName << std::endl;
}
void readInventory(std::string fileName, std::vector<Item>&inventory)
{
std::cout << "\tOpening " << fileName << std::endl;
std::fstream file(fileName.c_str(), std::ios::in);
if(file.good())
{
std::cout << "\t\tSuccess opening file" << std::endl;
while(!file.eof())
{
Item temp;
int readsize = 0;
file >> readsize;
if(readsize)
{
file.read((char*)&temp.itemDescription, readsize);
file >> temp.dateAdded;
file >> temp.quantity;
file >> temp.retailCost;
file >> temp.wholesaleCost;
inventory.push_back(temp);
std::cout << "\t\tRead item " << temp.itemDescription << std::endl;
}
}
}
else
std::cout << "\t\tFailed, a new file will be created when you save and exit." << std::endl;
file.close();
std::cout << "\tClosed " << fileName << std::endl;
}