Thread: Data Question about Reading Files: Encapsulated Inventory Program in C++

  1. #16
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Re:

    EVERY line with the infile.getline() statement as well as any line with the word 'record' in it is giving me an error because of the 'record' has not been declared error.

    the other error message ('listcurinv_1' in 'record' which is of non-aggregate type 'Inventory[100]') is on the line record.listcurinv_1(); found in main() .

  2. #17
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Unfortunately, you are attempting a program that is beyond your skill set at this point. You can try two things to get up to speed quickly:

    1) Create a small test class to learn about constructors, default constructors, and arrays. Your test class should have one private member and a method that displays the private member. Add any constructors you think you need. In main(), try to create an array of objects, and see if you can get that working.


    2) Write a short program that just does simple file input and output. Your program should mimic the file input you are trying to do for your program. In that regard, you can use an input file that has 5 products in it, but where you read in a maximum of 3 products. Work on that until you can successfully read in the data and display it to the console window.

    When you are having problems in a larger program, it is often helpful to create some small test programs to help you isolate and resolve the issues you are having--without having to deal with a lot of other junk at the same time.

  3. #18
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Here are some questions to consider about your code:

    1) Can methods of a class directly access the member variables of a class?

    2) Is record a member of your Inventory class?

    3) Can methods of a class refer to variables that are not member variables?

    4) How do you pass arrays to a function?
    Last edited by 7stud; 06-10-2005 at 11:45 PM.

  4. #19
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Re: 7stud

    I think I might have found out what the problem is. You can verify this if you'd like.

    The existance of "record" of type inventory does not exist in my
    class methods. Only in main where I declared it. I didn't pass any
    arguments to listcurinv_1 so it has created a scope error.

    The way I'm calling information about "record[i]" is redundant.
    I'm trying to read "record" of inventory type as if it were a
    text file. I'm ALREADY within record[i] since I called the
    method from main so I think I need to add some accessor methods to get at the data and change the name because it shouldn't be the same as the method call.

  5. #20
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Re:

    well FINALLY I at least was able to read in one record and get rid of the numerous compile errors that had been plaguing me for a while.

    Instead of using while (!infile.eof()) in my conditional loop which doesn't check other errors, would I be able to use while (infile) instead and would that work?

    I've changed the code around so that it at least reads in one record from the file so finally my compile errors are gone but I'm having problems with getting it into a loop and getting it to read every record from the file properly.

    Here is my UPDATED code:

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <cstdlib>
    #include <conio.h>
    #include <iomanip>
    
    class Inventory {
    
       private:
          int qty_stock, reord_lev;
          string ProdID, ProdDesc, manu;
          float unitcost;
    
       public:
          Inventory();
          Inventory(string, string, string, float, int, int);
          void listcurinv_1();
          void listcurinv_2();
          void add_stock();
          void rmv_stock();
          void add_prod();
          void rmv_prod();
          void calc_inv();
          void list_reord();
    };
    Inventory::Inventory(){}
    Inventory::Inventory(string id, string desc, string manufac, float cost, int
    qty, int r_level) {
       ProdID = id;
       ProdDesc = desc;
       manu = manufac;
       unitcost = cost;
       qty_stock = qty;
       reord_lev = r_level;
    }
    
    
    void Inventory::listcurinv_1() {
       cout << ProdID;
       cout << ProdDesc;
       cout << manu;
       cout << unitcost;
       cout << qty_stock;
       cout << reord_lev;
    }
    
    int main() {
    
       Inventory Product[100];
       char Values[3][100];
       char numvalues[3][100];
    
       ifstream infile("sportsstore.txt");
     
       // gets all the values in order: ProdID, ProdDesc, manu etc.
       infile.getline(Values[0], 10, ',');   // ProdID
       infile.getline(Values[1], 30, ',');   // ProdDesc
       infile.getline(Values[2], 15, ',');   // manu
       infile.getline(numvalues[0], 10, ',');   // unitcost
       infile.getline(numvalues[1], 5, ',');     // qty_stock 
       infile.getline(numvalues[2], 5);         // reord_lev
    
    // this is our temporary (current) product instance of class Inventory   InventoryTempProduct(Values[0],Values[1],Values[2],atof(numvalues[0]),atoi(numvalues[1]),atoi(numvalues[2]));
    
       Product[0] = TempProduct;
       Product[0].listcurinv_1();
       getche();
       return 0;
    }
    The key to getting rid of the compile errors was putting the infile statements in main() as opposed to inside the method. I also changed the data type of ProdID to a string because I am not doing any mathematical calculations on that field.

    I've tried getting it into a loop to read every record line from the file but it's not quite displaying properly.

    If anyone has any suggestions or advice, it would be greatly appreciated. Thanks.

  6. #21
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I've tried getting it into a loop to read every record line from the file but it's not quite displaying properly.
    About all I can suggest is that you go back to the beginning of the thread and reread all the posts. And, you should be doing this:

    2) Write a short program that just does simple file input and output. Your program should mimic the file input you are trying to do for your program. In that regard, you can use an input file that has 5 products in it, but where you read in a maximum of 3 products. Work on that until you can successfully read in the data and display it to the console window.
    would I be able to use while (infile) instead
    infile will evaluate to false if there are any stream errors, which includes eof, otherwise it will evaluate to true.

  7. #22
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Re: Program Update

    Well I've finally gotten through some of this program. The file I/O now reads and writes properly and I have the first four requirements coded.

    Here is my current code:

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <cstdlib>
    #include <conio.h>
    #include <iomanip>
    
    using namespace std;
    
    class Inventory {
    
       private:
          int qty_stock, reord_lev;
          string ProdID, ProdDesc, manu;
          float unitcost;
    
       public:
          Inventory();
          Inventory(string, string, string, float, int, int);
          void listcurinv();
          string get_desc();
          string get_id();
          string get_manu();
          float get_unitcost();
          int get_qty_stock();
          int get_reord_lev();
          int add_qty();
          int rmv_qty();
          void add_stock();
          void rmv_stock();
          void add_prod();
          void rmv_prod();
          void calc_inv();
          void list_reord();
    };
    
    Inventory::Inventory(){}
    
    Inventory::Inventory(string id, string desc, string manufac, float cost, int qty, int r_level) {
       ProdID = id;
       ProdDesc = desc;
       manu = manufac;
       unitcost = cost;
       qty_stock = qty;
       reord_lev = r_level;
    }
    
    
    void Inventory::listcurinv() {
       cout << setw(10) << ProdID;
       cout << setw(30) << ProdDesc;
       cout << setw(15) << manu;
       cout << setw(10) << unitcost;
       cout << setw(5) << qty_stock;
       cout << setw(5) << reord_lev << endl;
    }
    
    string Inventory::get_desc() {
       return ProdDesc;
    }
    
    string Inventory::get_id() {
       return ProdID;
    }
    
    string Inventory::get_manu() {
       return manu;
    }
    
    float Inventory::get_unitcost() {
       return unitcost;
    }
    
    int Inventory::get_qty_stock() {
       return qty_stock;
    }
    
    int Inventory::get_reord_lev() {
       return reord_lev;
    }
    
    int Inventory::add_qty() {
       int additem;
       cout << "Enter # of items to add to this product: ";
       cin >> additem;
       cin.ignore();
       qty_stock += additem;
       return qty_stock;
    }
    
    int Inventory::rmv_qty() {
       int rmvitem;
       cout << "Enter # of items to remove from this product: ";
       cin >> rmvitem;
       cin.ignore();
       while (rmvitem > qty_stock) {
          cout << "Can't remove this amount of items. Re-Enter amount: ";
          cin >> rmvitem;
          cin.ignore();
       }
       while (rmvitem <= 0) {
          cout << "Number entered must be greater than 0. Re-Enter amount: ";
          cin >> rmvitem;
          cin.ignore();
       }
       qty_stock -= rmvitem;
       return qty_stock;
    }
    
    
    int main() {
       char choice;
       int flag = 0;
       Inventory Product[100], spare;
       ifstream infile("c:\\sportsstore.txt");
       char Values[3][100];
       char numvalues[3][100];
       char eoln;   // ensures that final character of each line is read
       int p,j,k;
       string prodnum;
       int additem;
       p=0;
    
       while(1) {
           infile.getline(Values[0], 10, ',');
           if (infile.eof()) break;
           infile.getline(Values[1], 31, ',');
           infile.getline(Values[2], 15, ',');
           infile.getline(numvalues[0], 10, ',');
           infile.getline(numvalues[1], 5, ',');
           infile.getline(numvalues[2], 5, '\n');
           Inventory TempProduct (Values[0], Values[1], Values[2], atof(numvalues[0]), atoi(numvalues[1]), atoi(numvalues[2]));
           Product[p] = TempProduct;
           p++;
       }
    
       infile.close();
    
       while (flag == 0) {
          cout << "\t\t\n\n" << "**************************************************";
          cout << "\t\n\n" << "Sports Store Management Application";
          cout << "\t\n\n" << "**************************************************";
          cout << "\t\n\n" << "[L] List all the inventory sorted by product description.";
          cout << "\t\n" << "[I] List all the inventory sorted by product ID.";
          cout << "\t\n" << "[A] Add items to the stock of an existing product.";
          cout << "\t\n" << "[R] Remove items from the stock of an existing product.";
          cout << "\t\n" << "[C] Create an entry for a new product.";
          cout << "\t\n" << "[D] Delete all information for a product.";
          cout << "\t\n" << "[T] Show the total value of the entire inventory.";
          cout << "\t\n" << "[M] List those products needing to be reordered.";
          cout << "\t\n" << "[Q] Quit.";
          cout << "\t\n\n" << "Choice (enter lowercase letter option): ";
          choice = getche();
    
          switch(choice) {
             case 'l':
                system("cls");
    
                for (j = 0; j < p - 1; j++) {
                   for (k = 0; k < p-1; k++) {
                      if (Product[k].get_desc() > Product[k+1].get_desc()) {
                         spare = Product[k];
                         Product[k] = Product[k+1];
                         Product[k+1] = spare;
                     }
                   }
                }
    
                for (j = 0; j < p; j++) {
                   Product[j].listcurinv();
                }
                getche();
                system("cls");
                break;
    
             case 'i':
                system("cls");
                for (j = 0; j < p - 1; j++) {
                   for (k = 0; k < p - 1; k++) {
                      if (Product[k].get_id() > Product[k+1].get_id()) {
                         spare = Product[k];
                         Product[k] = Product[k+1];
                         Product[k+1] = spare;
                      }
                   }
                }
    
                for (j = 0; j < p; j++) {
                   Product[j].listcurinv();
                }
                getche();
                system("cls");
                break;
    
             case 'a':
                system("cls");
                cout << "Enter a product ID number to add items to: ";
                cin >> prodnum;
             //   cin.ignore();
                for (j = 0; j < p; j++) {
                   if (prodnum == Product[j].get_id()) {
                      Product[j].add_qty();
                      break;
                   }
                }
                system("cls");
                break;
    
             case 'r':
                system("cls");
                cout << "Enter a product ID number to remove items from: ";
                cin >> prodnum;
                cin.ignore();
                for (j = 0; j < p; j++) {
                   if (prodnum == Product[j].get_id()) {
                      Product[j].rmv_qty();
                      break;
                   }
                }
                system("cls");
                break;
    
             case 'q':
                flag = 1;
                break;
    
             default:
                cout << "\nInvalid selection. Press a key to return to main menu.";
                getche();
                system("cls");
          }
    
          if (flag == 1) {
             break;
          }
       }
    
       ofstream outfile("c:\\sportsstore.txt");
       for (j = 0; j < p; j++) {
          outfile << Product[j].get_id();
          outfile << "," << Product[j].get_desc();
          outfile << "," << Product[j].get_manu();
          outfile << "," << Product[j].get_unitcost();
          outfile << "," << Product[j].get_qty_stock();
          outfile << "," << Product[j].get_reord_lev() << endl;
       }
       return 0;
    }
    I do have one question though. How can I error check for when a user enters an alphanumeric when it should be a numeric value?

    Can something like isalpha() or something to that effect work?

  8. #23
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Can something like isalpha() or something to that effect work?
    No. If you try to read a string into a variable with a numeric type, the read will fail and the stream will enter error mode. Therefore, there won't be anything in the numeric variable to use isalpha() on.

    You would have to read everything in as a string, and then see if the string contains digits or not. You could do that by checking the characters in the string using isalpha(), or you could use stringstreams to try and convert a string to a number.
    Last edited by 7stud; 06-14-2005 at 04:44 PM.

  9. #24
    Registered User
    Join Date
    Nov 2004
    Posts
    73
    Is it a good practice to use cin.ignore() every time you use cin to get user input? That's what I'm doing in this program.

    I had problems with previous programs due to not including that after the cin statements.

  10. #25
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Is it a good practice to use cin.ignore() every time you use cin to get user input?
    Not generally. If you only use '>>' for reading input, then cin.ignore() is unnecessary. The operator>> skips leading whitespace, so the \n that is left in the input after reading data will be skipped the next time you read data with the operator>>. However, if you use the operator>> for reading input and then subsequently use getline(), you need to use cin.ignore() to remove the \n.

  11. #26
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Re: Deleting a Record from the file

    I'm having some trouble understanding what I have to code for removing a product record from the file (having all it's field information be deleted). The code that I currently have for that section is not working. It asks the user to enter the Product ID of the file they wish to delete and then the program should find the record and delete it. I would like it to be able to move all the records in the file up 1 position from the position of the file that was deleted so that there are no blanks in the file.

    I've attached my code since it's a little different because it involves classes.


    It's the last part that I need to get working on this program.

    Any help or advice would be greatly appreciated on this subject. Thanks.

  12. #27
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    You need to:

    1) read in the whole file

    2) close the file

    3) reopen the file which will erase it

    4) write only the the lines you want back to the file

    To accomplish 4), you can create a string variable called newData:

    string newData;

    When you read in each line of your file in 1), check the Product ID. If there isn't a match, add the line to newData, if there is a match, don't add the line to newData. After you read in your whole file, newData will have every line except the line you want to delete. Then, write newData to the file.

    You'll have to add a '\n' after every line you add to newData because when you use getline() to read in the data, getline() removes the '\n' at the end of every line. So, if you don't add a '\n' after every line you add to newData, the new data will end up being one long continuous line.
    Last edited by 7stud; 06-15-2005 at 02:43 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. reading data contents from files in c++
    By shaheel in forum C++ Programming
    Replies: 4
    Last Post: 04-13-2008, 09:02 PM
  2. Reading large complicated data files
    By dodzy in forum C Programming
    Replies: 16
    Last Post: 05-17-2006, 04:57 PM
  3. Question about IOStream and reading strings from files
    By kingpinzs in forum C++ Programming
    Replies: 22
    Last Post: 12-13-2005, 11:29 AM
  4. Program Crashing
    By Pressure in forum C Programming
    Replies: 3
    Last Post: 04-18-2005, 10:28 PM
  5. reading data format into program
    By lambs4 in forum C Programming
    Replies: 1
    Last Post: 10-23-2003, 02:27 PM