Binary Inputs and Outputs *Files Questions

This is a discussion on Binary Inputs and Outputs *Files Questions within the C++ Programming forums, part of the General Programming Boards category; Sorry, this is going to be a very long post first of all,here is my codes: Header File Code: struct ...

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    37

    Binary Inputs and Outputs *Files Questions

    Sorry, this is going to be a very long post

    first of all,here is my codes:

    Header File
    Code:
    struct hardware
    {
    	int record;
        char name[100];
        int quantity;
        float cost;
    };
    Binary Input File cpp
    Code:
    #include<iostream>
    #include<iomanip>
    #include<fstream>
    #include <cstring>
    #include "hardware.h"
    using namespace std;
    
    void get_data(hardware *);
    void show_hardware();
    
    fstream emp_file;  // global fstream object
    
    void main()
    {
        hardware temp;
    
        emp_file.open("empfile.bin", ios::in | ios::out | ios::trunc | ios::binary);
    
        if (!emp_file)
        {
            cout << "\nCannot open hardware file";
        	exit(1);
        }
    
        cout << "Enter some lines of hardware data\n"
             << "(Enter Ctrl-Z to stop)\n\n";
        while (!cin.eof() )
        {
    	    get_data(&temp);
    	    if(!cin.eof() )
         	{
                emp_file.write( (char *)&temp, sizeof(hardware) );
    	    }
        }
    
    
        show_hardware();
        emp_file.close();
    
        cout << "\n\n";
    
    }
    
    void get_data(hardware *pwkr)
    {
        static int i = 0;
        int j;
    
        i++;
        for(j = 0; j < 20; j++) pwkr->name[j] = ' '; // set array to spaces
    	cout << "Enter the Record#, "
    		<<"Tool Name, Quantity and the Cost "
    		<<"for Hardware #" << i << " : ";
        cin >> pwkr->record>> pwkr->name >> pwkr->quantity >> pwkr->cost;
    }
    
    
    void show_hardware()
    {
        int i = 0;
        hardware temp;
    
        cout << "\n\nThese are the Hardware Tools in the System\n"
             << setiosflags(ios::showpoint | ios::fixed);
    	cout << "Tool\tRecord# Tool Name\tQuantity\tCost";
        emp_file.seekg(0,ios::beg);
        emp_file.read( (char *)&temp, sizeof(hardware) );
        while ( !emp_file.eof() )
        {
            i++;
            cout << "\n" << i << "\t"
                 << temp.record << "\t"
                 << temp.name << "\t\t"
                 << temp.quantity << "\t\t "
    			 << setprecision(2)
                 << temp.cost;
            emp_file.read( (char *)&temp, sizeof(hardware) );
        }
    }
    Binary Direct Input & Output cpp
    Code:
    #include<iostream>
    #include<iomanip>
    #include<fstream>
    //#include <process.h>
    #include <cstring>
    #include "hardware.h"
    using namespace std;
    
    void set_money_display(void);
    int retrieve_hardware(hardware *);
    void alter_data(hardware *, int);
    void update_hardware(hardware *, int);
    void show_hardware();
    
    fstream emp_file ("empfile.bin", ios::in | ios::out | ios::binary );
    
    void main()
    {
        char choice;
        hardware temp;
        int posn;
    
        set_money_display();
        if (!emp_file)
        {
    	cout << "Cannot open file - empfile.bin";
    	exit(1);
        }
        show_hardware();
        cin.get();
        posn = retrieve_hardware(&temp);
        alter_data(&temp, posn);
    
        cout << "\nDo you want to store these changes? ";
        cin >> choice;
        if (choice == 'y' || choice == 'Y')
        {
    	update_hardware(&temp, posn);
        }
        show_hardware();
        emp_file.close();
    
        cout << "\n\n";
    
    }
    
    void set_money_display()
    {
        cout << setprecision(2)
    	 << setiosflags(ios::fixed | ios::showpoint);
    }
    
    int retrieve_hardware(hardware *ptemp)
    // get the data of an hardware in the file
    {
        int posn;
    
        cout << "\n\nEnter the position number of a hardware in the file\n";
        cin >> posn;
        cin.get();
        posn --;
        emp_file.clear();
    	emp_file.seekg(posn * sizeof(hardware),ios::beg);
        emp_file.read( (char *)ptemp, sizeof(hardware) );
        return(posn);
    }
    
    void alter_data(hardware *ptemp, int posn)
    //get user to key in new hardware details
    {
        char tname[20];
    
        cout << "Enter new details for hardware " << (posn + 1) << "\n";
        cout << "Name:  " << ptemp->name << "  ";
        cin.getline(tname, 19);
        if (tname[0] != '\0')  // a new name was input
        {
    	strcpy(ptemp->name,tname);
        }
    	cout << "Record#:  " << setw(2) << ptemp->record << "  ";
        cin >> ptemp->record;
        cout << "Quantity:  " << setw(2) << ptemp->quantity << "  ";
        cin >> ptemp->quantity;
        cout << "Cost: " << setw(2) << ptemp->cost << "  ";
        cin >> ptemp->cost;
    }
    
    void update_hardware(hardware * ptemp, int posn)
    // overwrite the old hardware details in the file
    {
        emp_file.seekp(posn * sizeof(hardware),ios::beg);
    	emp_file.write( (const char *)ptemp, sizeof(hardware) );
    }
    
    void show_hardware()
    {
        int i = 0;
        hardware temp;
    
        cout << "\n\nThese are the hardware in the file\n"
    	 << setiosflags(ios::showpoint | ios::fixed);
        cout << "Hardwar\tRecord# Tool Name\tQuantity\tCost";
        emp_file.seekg(0,ios::beg);
        emp_file.read( (char *)&temp, sizeof(hardware) );
        while ( !emp_file.eof() )
        {
    	i++;
    	cout << "\n" << i << "\t"
    	     << temp.record <<"\t"
    	     << temp.name << "\t\t"
    	     << temp.quantity << "\t\t"
    		 << setprecision(2)
    	     << temp.cost << "   ";
    	emp_file.read( (char *)&temp, sizeof(hardware) );
        }
    }
    now here is my question and concerns:
    1) i need to be able to input a list of hardware tools and for each hardware there needs to include these informations: (record #, name, quantity and cost).
    this part is done, i was able to do it after i used the Binary Input File cpp.

    a)but there is a problem when i try to enter the name.
    for example: if i enter Screw Driver(with space then the program will crash. but if i enter Screw_Driver(with underscore) then i am ok. ???

    2) after i enter a few hardware tools i need to able to update the information or delete it if i want to.
    so i used Binary Direct Input and Output cpp.

    Sample output when i run Binary Direct Input and Output

    Hardware Record# Tool Name Quantity Cost
    1 68 Screw_Driver 106 6.99
    2 83 Wrench 34 7.50

    two issues here
    a)i am able to update any information i want but i need to refer to the hardware number(1,2..). how do i change my code so i can refer to the record # of the hardware if i want to change/update a hardware information?

    b)how do i delete a hardware complete?

    3)lastly, where do i go if i want to check what is being stored after i used Binary Input File cpp. is there suppose to be a .DAT file created after i compile the Binary Input File?
    i check my folder where these cpp and header files are located but there is none.

    thanks.

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,173
    void main is undefined! Read my signature and use int main.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.
    For information on how to enable C++11 on your compiler, look here.
    よく聞くがいい!私は天才だからね! ^_^

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Really, if you are using binary format, you should also use the binary read/write functions, not >> and << operators. If you are using >> and <<, then the file isn't supposed to be a binary file.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,173
    The OP uses read & write for the binary fstream object which is global.
    Avoid globlal variables!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.
    For information on how to enable C++11 on your compiler, look here.
    よく聞くがいい!私は天才だからね! ^_^

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    37
    anyone?

  6. #6
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    a)but there is a problem when i try to enter the name.
    for example: if i enter Screw Driver(with space then the program will crash. but if i enter Screw_Driver(with underscore) then i am ok. ???
    You'll find the answer to this one here.

  7. #7
    Registered User
    Join Date
    Oct 2007
    Posts
    37
    can someone please show a example of how i can delete a record completely. thanks

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Here are some of essential ways of "removing" something from a binary file:
    1. You have some way to MARK a record deleted, and you use this to indicate which fields are "no longer active".

    1b) As 1, but you have a "header" record at the beginning of the file [it's by far easiest if this is the same size as all other records, but you CAN have it another size if you want], which contains the first deleted entry, and each subsequent record contains the "next" deleted record. When you delete something, you write the current "last deleted" into the deleted item, and the record of the deleted into the header.

    2. You move some data from the end of the file "one step up" [you can for example move the last record to the "deleted" entry], and then use a function call to "truncate" the file - although this is not entirely portable, what works on Linux won't work on Windows, or the other way around.

    3. Copy the data from the original file to a new file [or load all the data into memory, remove the relevant record, then write all the data back out again].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,173
    The last two can be expensive operations especially if the file is big. I recommend the 2nd method (1B).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.
    For information on how to enable C++11 on your compiler, look here.
    よく聞くがいい!私は天才だからね! ^_^

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    The last two can be expensive operations especially if the file is big. I recommend the 2nd method (1B).
    Yes, they are sort of listed in "order of performance vs. ease of implementation". If your database is several megabytes, then doing a complete copy of the whole thing will be horribly inefficient. Fortunately, most small projects don't have HUGE databases, so it's not really a problem.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    If you have a huge DB, you shouldn't roll your own file format in the first place.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by CornedBee View Post
    If you have a huge DB, you shouldn't roll your own file format in the first place.
    True enough.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    can someone please show a example of how i can delete a record completely. thanks
    Code:
    #include<iostream>
    #include<iomanip>
    #include<fstream>
    #include <cstring>
    using namespace std;
    
    struct hardware
    {
        char flag[1];
        int record;
        char name[100];
        int quantity;
        float cost;
    };
    
    void editrec(char *fname, int record, char *newname)
    {
        long int pos;
        int count=0;
        hardware temp = {0};
        fstream file, outfile;
        file.open(fname, ios::in | ios::out  | ios::binary );
        file.seekg(0,ios::beg);
        file.read((char *)&temp, sizeof(hardware));
        while (!file.eof())
        {
            if (temp.record == record)
            {
                strcpy(temp.name, newname);
                pos=count*sizeof(temp);
                file.seekp(pos,ios::beg);
                file.write((char*)&temp,sizeof(hardware));
                file.close();
                break;
            }
            count++;
            file.read( (char *)&temp, sizeof(hardware) );
        }
    }
    
    void deleterec(char *fname, int record)
    {
        long int pos;
        int count=0;
        hardware temp = {0};
        fstream file, outfile;
        file.open(fname, ios::in | ios::out  | ios::binary );
        file.seekg(0,ios::beg);
        file.read( (char *)&temp, sizeof(hardware) );
        while ( !file.eof() )
        {
            if (temp.record == record)
            {
                temp.flag[0]='*';
                pos=count*sizeof(temp);
                file.seekp(pos,ios::beg);
                file.write((char*)&temp,sizeof(hardware));
                break;
            }
            count++;
            file.read( (char *)&temp, sizeof(hardware) );
        }
        outfile.open("Temp.bin",ios::out | ios::binary);
        file.seekg(0,ios::beg);
        while(file.read((char*)&temp,sizeof(temp)))
        {
            if(temp.flag[0]!='*')
                outfile.write((char*)&temp,sizeof(temp));
        }
        outfile.close();
        file.close();
        remove(fname);
        rename("temp.bin",fname);
        remove("temp.bin");
    }
    
    void get_data(char *fname)
    {
        string dummy;
        int j;
        hardware pwkr = {0};
        fstream update_file(fname,ios::out|ios::binary|ios::app); 
        for(j = 0; j < 20; j++) pwkr.name[j] = ' '; // set array to spaces
        cout << "Record #: ";
        cin >> pwkr.record;
        //Get rid of the newline inserted by the environment
        cin.ignore(1,'n');
        cout << "Tool Name: ";
        cin.getline( pwkr.name, sizeof(pwkr.name) );
        cout << "Quantity: ";
        cin >> pwkr.quantity;
        cout << "Cost: ";
        cin >> pwkr.cost;
        update_file.write(reinterpret_cast<char *>(&pwkr),sizeof(hardware));
        update_file.close();
    }
    
    void show_hardware(char *fname)
    {
        int i = 0;
        hardware temp = {0};
        fstream show_file(fname,ios::binary|ios::in);
        cout << "\n\nThese are the Hardware Tools in the System\n"
            << setiosflags(ios::showpoint | ios::fixed);
        cout << "Tool\tRecord# Tool Name\tQuantity\tCost";
        show_file.seekg(0,ios::beg);
        show_file.read( (char *)&temp, sizeof(hardware) );
        while ( !show_file.eof() )
        {
            i++;
            cout << "\n" << i << "\t"
                << temp.record << "\t"
                << temp.name << "\t\t"
                << temp.quantity << "\t\t "
                << setprecision(2)
                << temp.cost;
            show_file.read( (char *)&temp, sizeof(hardware) );
        }
        show_file.close();
    }
    
    int main(void)
    {
        get_data("empfile.bin");
        show_hardware("empfile.bin");
        editrec("empfile.bin", 1, "Dewalt");
        show_hardware("empfile.bin");
        deleterec("empfile.bin", 1);
        show_hardware("empfile.bin");
        return 0;
    }

  14. #14
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,173
    I would use an index myself or a flag in the record instead of writing out *** everywhere in the record. This could be mistaken for actual data.
    Anyway, both methods are fine. It's just one lengthy example
    But it demonstrates the point - the example is a good one.
    Last edited by Elysia; 12-21-2007 at 06:13 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.
    For information on how to enable C++11 on your compiler, look here.
    よく聞くがいい!私は天才だからね! ^_^

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do i ouput multiple inputs?
    By vodka9er in forum C++ Programming
    Replies: 2
    Last Post: 11-19-2007, 08:45 AM
  2. Human brain and programing
    By avgprogamerjoe in forum A Brief History of Cprogramming.com
    Replies: 26
    Last Post: 08-27-2007, 04:48 PM
  3. Replies: 5
    Last Post: 11-21-2004, 03:39 PM
  4. Collision with quads?
    By SyntaxBubble in forum Game Programming
    Replies: 6
    Last Post: 01-18-2002, 05:17 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21