URGENT - file operation question

Hi everyone,

I am taking coding class and I couldn't figure out a homework question for the life of me (I might just be too dumb for coding Ha!). If you could help me out (as in write out the whole thing for me), I would really appreciate it (meaning I'll pay you). PLEASE PM ME! :)

Finally, let me slip in a little self defense here: I do want to learn how to code but right now is not a good time for me as I am in the process of applying for secondary schools!

To give you a little more information, this chapter focuses on file operation, binary file, random access files. Please focus on these basic concepts even if you know a better/faster way to solve it, thanks!

Here is the homework question:

Write a program that uses a structure to store the following inventory data in a file: The data can be
either read from a text file or the keyboard
 Item name (string)
 Quantity on hand(int)
 Wholesale cost(double)
 Retail Cost(double)
The program should have a menu that allows the user to perform the following tasks:
1. Add new records to the file
2. Display any record in the file
a. User will provide the name of the item or the first n letters of the name of the item
3. Change any record in the file (Note: if this option chosen, then the whole record must be
reentered even if the user wants to change only one or more fields)
4. Display all records
5. Prepare a report containing:
a. The total wholesale value of the inventory
b. The total retail value of the inventory
c. The total quantity of all values in the inventory.
Input validation: The program should not accept quantities or wholesale or retail
costs less than 0.


Here is what I have so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <fstream>
#include <cctype>
#include <cstring>
using namespace std;

struct data
{
    string name;
    int quantity;
    double wholeCost, retailCost;
    
};


int main()
{
    fstream record ("record.txt", ios::out | ios::binary);
    
    data inventory;
    char more;
    
    do
    {
        cout << "\nitem name: " ;
        getline(cin, inventory.name);
      
        cout << "quantity on hand: ";
        cin >> inventory.quantity;
        cin.ignore();
        
        cout << "wholesale cost: ";
        cin >> inventory.wholeCost;
        cin.ignore();
        
        cout << "retail cost: ";
        cin >> inventory.retailCost;
        cin.ignore();
        
        record.write((char*)&inventory, sizeof(inventory));
        
        cout << "\nEnter y if you would like to enter more data: ";
        cin >> more;
        cin.ignore();
        
    }while (toupper(more)=='Y');
    
    record.close();
}  



Last edited on
Just a follow up. I am using Xcode 7.3. When I created the txt file using the code above and input the information, I got weird symbols for the number part of the file. Any idea why would that be? Thank you.
Try using
ofstream record ("record.txt", ios::binary);
instead of
fstream record ("record.txt", ios::out | ios::binary);
to open the file.

Try using [Edit.This is accepted to be wrong advice - please note jlb's correction below.]
record.write(inventory, sizeof(inventory));
instead of
record.write((char*)&inventory, sizeof(inventory));
to write the item.


Note: I'm not sure whether this is going to work in the long run, as one item in the inventory is not of fixed size (it's a string). Thus, finding this subsequently in the binary file (as you are expected to change the inventory) may be difficult. Maybe this is one place where a null-terminated character array (C string) might be easier.
Last edited on
You will need to convert each member to a C-string before calling write(), otherwise each member will be casted to a C-string, resulting in "weird symbols". See http://www.cplusplus.com/reference/string/to_string/

I'd recommend you use the overloaded operator<< instead.
1
2
3
4
record << inventory.name << "\t" << 
	inventory.quantity << "\t" << 
	inventory.wholeCost << "\t" << 
	inventory.retailCost << "\n";
Try using
ofstream record ("record.txt", ios::binary);
instead of
fstream record ("record.txt", ios::out | ios::binary);
to open the file.

Please explain you're reasoning behind this recommendation.


Try using
record.write(inventory, sizeof(inventory));
instead of
record.write((char*)&inventory, sizeof(inventory));
to write the item.

No, std::ostream.write() expects a char* as the first argument, therefor you will need to cast any variable that is not a character pointer to the correct type. However the OP should be using C++ style casts instead of the more dangerous C style cast.
record.write(reinterpret_cast<char*>(&inventory), sizeof(inventory));


When I created the txt file using the code above and input the information, I got weird symbols for the number part of the file. Any idea why would that be?

Those "weird symbols" are the address of the string variables contained in your structure. You can't use the write() method to directly write a non-POD data type, like a std::string. To write a std::string to a binary file using write() you need to first write the length of the string to the file, then write the C-string representation of the string to the file. Something like:

1
2
3
4
5
6
7
    std::ofstream datafile("test.dat", std::ios::binary);

    std::string someData = "This is a string.";
    size_t len = someData.length();
    datafile.write(reinterpret_cast<char*>(&len), sizeof(len));
    // Now write out the actual string.
    datafile.write(someData.c_str(), len);


Please explain you're reasoning behind this recommendation.

Well, it is exactly what you are using in your own example!
std::ofstream datafile("test.dat", std::ios::binary);


No, std::ostream.write() expects a char* as the first argument,

Yes, I have to accept I was wrong here. I have edited my post above to acknowledge that it was poor advice. Sorry!
Last edited on
Well, it is exactly what you are using in your own example!

So? I asked you to explain you're reasoning for recommending ofstream over fstream. While I may or may not prefer ofstream over fstream, that is not the point. The fstream class is a perfectly usable class why do you feel that ofstream is a better choice?

Topic archived. No new replies allowed.