Reading then overwriting to a text file

I don't have any errors when I compile, so that's a good start. :)

I need to read a text file. Then I need to view, write over data, and add an additional entry (I have it set to 2 now for testing purposes).

Right now, when I read, I just get a bunch of gobbledy gook and my choices seem to loop and don't go back to the menu when one entry has been accessed.

THANK YOU TO ALL THAT READ THIS. (I removed sections to make it a shorter read. If you can show me what I'm doing wrong, I can apply it to the other functions.)

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>  
#include <fstream>  
#include <iomanip>  
#include <cctype>  
using namespace std;  
  
const int DESC_SIZE = 51;								
const int DATE_SIZE = 51;	
const int NUM_RECORDS = 2;//just 2 for testing purposes
struct InventoryItem								    
{  
    char desc[DESC_SIZE];								
    int quantity;										
    double whlCost;											
    double rtlCost;								 
    char date[DATE_SIZE];								
    int menu();
};   
//void addRec(fstream &); removed for a shorter read							
//void dispRec(fstream &);removed for a shorter read								
void chgRec(fstream &);								

 int InventoryItem::menu()
 {  
	 int choice;  
	 cout << "Please make a selection, 1 through 4." << endl; 
     cout << "1. Add a new record" << endl;  
     cout << "2. View an exisitng record" << endl;  
     cout << "3. Change an exisitng record" << endl;  
     cout << "4. Exit" << endl;  
     cout << endl;  
     cout <<"Enter your choice (1-4): ";  
     cin >> choice;  
   
}  
  
//removed void addRec(fstream &file)to make it a shorter read											
//removed void dispRec(fstream &file) to make it a shorter read

void chgRec(fstream &file)								
{  
      
     InventoryItem record;   
     long recNum;  
	 fstream inventory ("inventory.txt", ios::in | ios::out);
	  if (!inventory)
	{
		cout << "Error opening file.";
	}
     cout << "Enter the record number of the item you want to edit: ";  
     cin >> recNum;											
     inventory.seekg(recNum * sizeof(record), ios::beg);  
     inventory.read(reinterpret_cast<char *>(&record),sizeof(record));  
	 cout << "Description: ";
	 cout << record.desc << endl;  
         cout << "Quantity: ";
	 cout << record.quantity << endl;  
         cout << "Wholesale cost: ";
	 cout << record.whlCost << endl;  
         cout << "Retail price: ";
	 cout << record.rtlCost << endl;  
	 cout << "Date (in 00/00/0000 format): ";
	 cout << record.date << endl;
	 cout << "Enter the new data." << endl;
         cout << "Description: ";
	 cin.ignore();
	 cin.getline(record.desc, DESC_SIZE);
	 cout << "Quantity: ";
	 cin >> record.quantity;  
         cout << "Wholesale cost: ";
	 cin >> record.whlCost; 
         cout << "Retail price: "; 
	 cin >> record.rtlCost;
	 cout << "Date (in 00/00/0000 format): ";
	 cin >> record.date;    
     inventory.seekp(recNum * sizeof(record), ios::beg);  
     inventory.write(reinterpret_cast<char *>(&record),sizeof(record));  
     inventory.close();  
}

int main()  
{ 
   	
	string word;
	long selection;										 
	InventoryItem test;
	selection = test.menu();
        InventoryItem record = {" ", 0, 0.0, 0.0, " "};  
        cout << fixed << showpoint << setprecision(2);  
        cout<<"Inventory Managment"<<endl;  
	fstream inventory ("inventory.txt", ios::out);
	if (inventory.is_open())
	{
		cout << "Opening file.\n";
	}
 
		while (selection != 4) 
        {  
        switch(selection)  
       //removed other cases to shorten read 
        case 3:													
            {   chgRec(inventory);  
                break;  
            }  
        default:												
            {  cout << "Invalid selection" << endl;  
            }  
            selection = record.menu();  
        }  
        }               
    inventory.close();      
    return 0;  
 }  
Your menu() function never returns a value. Your compiler should have warned you about that.

Also, the way you've read your data in is completely wrong. You're assuming that the cast will automatically de-serialize your data from string form to structure form, and in reality, it is much more complicated than that. I suggest you read up on the stream extraction operator (operator>>) and getline() and use them to appropriately read in your input.

Edit: Since you already pass in the open filestream into your function, you should just use that reference instead of trying to open the file again. And the same issue goes for outputting your data.
Last edited on
I really appreciate your time, yulingo. However, I don't understand. I'm using a C++ Early Objects book and it doesn't give good examples.

I'm trying to get the 3 examples from the book to work together. Each was originally a main function, that's probably why the opening and closing of the file doesn't make sense.

Can you elaborate on your suggestions, please?

Thank you very much for your time and efforts. :)
Did the example actually have this line in it?
inventory.read(reinterpret_cast<char *>(&record),sizeof(record));
Yes. It says "it reads and displays the records".
Last edited on
Are your files actually text files or are they just some data file?
I am trying to use text files so I can view them to help troubleshoot my problem. I have populated the file with data and left the file blank. Neither fixes the problem.

well you can't use text values with this parsing method. You have to add a few entries first and try reading them back out to see if you can parse what you wrote.

Let me clarify:
the read() function reads in a block of data from a file, literally as a bunch of raw bytes. Therefore, the data in the file has to be in raw byte form, whch is not the same as text in a text file. For example, a double value like 2.3 is actually stored in 8 bytes of computer memory. the reinterpret_cast can't magically transform "2.3" in a text file into a double value.
Last edited on
Ok. I follow you.

The way my code is written, will it save my entries, or will it delete them all when I close the program. (The book never says what happens to the entries).

Should I change the file I'm writing to into a .dat file?

Thank you for all of your time and efforts!

How do I stop the loop once I enter an entry and go back to the menu selection? I can't test if it stores anything because it keeps going to "Enter the record number of the item you want to edit:"
Last edited on
well it really doesn't matter which extension you use, because no matter what, you can still try to open the file in a text editor and it won't look like a normal list of data because it is all in raw bytes.

That is the biggest drawback to these examples-you can't actually see if something is written wrong unless you read it back. That's why so many assignments are about text parsing.
Topic archived. No new replies allowed.