0

I am currently working on a program that uses structures to write records to a file. It is supposed to be a program that keeps inventory of different items on a file. It displays a menu asking the user what they would like to do. When I choose the same option (Add Item) twice in a row. Can anyone tell me why this is happening?

//Kylie Sanderson
/**********************************************************************************
C++ Early Objects: Chapter 13, Page 896
15. Inventory Program
Write a program that uses a structure to store the following inventory
information in a file:
Item description
Quantity on hand
Wholesale cost
Retail cost
Date added into inventory
The program should have a menu that allows the user to perform the following tasks
Add new records to the file
Display any record in the file
Change any record in the file
Display all records in the file
************************************************************************************/

#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <cctype>
using namespace std;

struct InventoryItem{
char description[25];
int quantity;
char wholesale[10];
char retail[10];
char date[10];
};

int displayMenu();
void addItem();
void displayItem();
void changeItem();
void displayAllItems();

fstream infoFile;
InventoryItem record;
int recordCount = 0;

int main(){
    int userI;

    cout << "Welcome to the Inventory Tracker." << endl;

    while(userI != 0){
        userI = displayMenu();

        if(userI == 1){
            recordCount++;
            addItem();
        }
        else if(userI == 2){
            displayItem();
        }
        else if(userI == 3){
            changeItem();
        }
        else if(userI == 4){
            displayAllItems();
        }
        else{
            return 0;
        }
    }
}

int displayMenu(){
    string tab;
    tab.assign(5, ' ');
    int response;

    cout << "What would you like to do?" << endl;
    cout << tab << "(1)Add New Item" << endl;
    cout << tab << "(2)Display Item" << endl;
    cout << tab << "(3)Change Item" << endl;
    cout << tab << "(4)Display All Items" << endl;
    cout << tab << "(0)Quit" << endl;
    cin >> response;
    cin.clear();
    cin.sync();
    return response;
}

void addItem(){
    infoFile.open("inventory.dat", ios::app | ios::binary);
    string des;
    cout << "You chose to add a new item to the inventory." << endl;

    cout << "Enter a description of the item up to 25 characters: ";
    getline(cin, des);
    for(int i = 0; i < 25; i++){
        des[i] = toupper(des[i]);
    }
    strcpy(record.description, des.c_str());
    cin.clear();
    cin.sync();

    cout << "Enter the quantity of the item: ";
    cin >> record.quantity;
    cin.clear();
    cin.sync();

    cout << "Enter the wholesale cost of the item: ";
    cin >> record.wholesale;
    cin.clear();
    cin.sync();

    cout << "Enter the retail cost of the item: ";
    cin >> record.retail;
    cin.clear();
    cin.sync();

    cout << "Enter the date of entry (dd/mm/yyyy): ";
    cin >> record.date;
    cin.clear();
    cin.sync();

    infoFile.write(reinterpret_cast<char*>(&record), sizeof(record));
    infoFile.close();
}
void displayItem(){

    cout << "You chose to display an item from the inventory." << endl;
}

void changeItem(){

    cout << "You chose to change an item in the inventory." << endl;
}

void displayAllItems(){

    infoFile.open("inventory.dat", ios::in | ios::binary);
    infoFile.seekg(0, ios::beg);
    char response;
    cout << "You chose to display all items in the inventory." << endl;
    while(!infoFile.eof()){
        infoFile.read(reinterpret_cast<char*>(&record), sizeof(record));
        cout << setw(16) << left << "Description: " << record.description << endl;
        cout << setw(16) << left << "Quantity: " << record.quantity << endl;
        cout << setw(16) << left << showpoint << setprecision(2) << "Wholesale Cost: " << record.wholesale << endl;
        cout << setw(16) << left << showpoint << setprecision(2) << "Retail Cost: " << record.retail << endl;
        cout << setw(16) << left << "Date of Entry: " << record.date << endl;
        cout << "Press any key to see the next item.";
        cin >> response;
    }
}
  • Wow, all those `endl`s! `cout` is certainly flushed! (Use `'\n'` when you just need to end a line) – Pete Becker Dec 11 '15 at 02:02
  • What do you think happens when `des` is less than 25 chars? What do you think will happen when it's more than 25 chars? `while(!infoFile.eof())` is almost [always wrong](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – user657267 Dec 11 '15 at 02:06
  • the specific point it stops working is when trying to set the wholesale variable in the structure when using the addItem function if that helps anyone. and I just replaced all the endl with \n – Kylie Sanderson Dec 11 '15 at 02:07
  • Since `record.wholsale` is 10 characters long, the input text should only have 9 characters. That's just a guess of course, since there's no sample input. – Pete Becker Dec 11 '15 at 02:25
  • it's not working no matter what data type wholesale is – Kylie Sanderson Dec 11 '15 at 02:34

2 Answers2

0

Your corrupting memory when you don't check the input length and tell the program to run the following block of code.

The for loop needs on each character entered not the supported max length.

string des;
cout << "You chose to add a new item to the inventory." << endl;

cout << "Enter a description of the item up to 25 characters: ";
getline(cin, des);
for(int i = 0; i < 25; i++){
    des[i] = toupper(des[i]);
}
0

It worked fine for me, compiled and ran. issues i ran into: when adding an item, any description less than 25 characters long throws an error. fix by changing the for loop parameters. for(int i = 0; i < des.length(); i++) then only copy the first 24 characters and cat a \0 at the end, or expand the size of description, or change it from a char[] to a std::string

unfortunately I was unable to recreate the error you are asking about

Bubba Doe
  • 46
  • 8
  • that fixed the error i was having! would you mind looking at another area of the code? i've been working on this for two days straight and hitting dead ends. after entering items, the displayAllItems function is supposed to show every item but it is only showing the most recently inputted item. do you see why that might be? – Kylie Sanderson Dec 11 '15 at 04:24