Jump to content
  • Advertisement
Sign in to follow this  
angelxe1

help with struct and i/o please

This topic is 4942 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

how can i read from a file written in binary to a struct? here is my program - it's homework so i realize the program is pretty pointless. i am having problems writing the info on the file into the struct temprec - it only reads into temprec[0].name and temprec[0].amnt but all data after that is garbage binary - the whole program is bellow. i'm a newbie so please bear with me.
 
struct record
{
	char name[15];
	float amnt;
};

struct temp
{
	char name[15];
	float amnt;
};


void main()
{
	ofstream fout;

	fout.open("master.dat", ios::binary);
	
	record master [10] = {"Helen", 10, "Julie", 20, "Lena", 30, 
		"Alan", 40, "Annie", 50, "May", 60, "Lee", 70, "Sam", 80, "June", 90, 
"Bill", 100};
	
	fout.write((char*)&master, sizeof(record));
	fout.close();

	fout.open("trans.dat", ios::binary);
	
	struct record trans [7] = {"Lena", 10, "Julie", 5.75, "Lee", 15.02,
		"Ed", 40, "Art", 5.00, "Bill", 7.32};

	fout.write((char*)&trans, sizeof(record));
	fout.close();

	temp temprec[10];
	ifstream fin;
	fin.open("master.dat", ios::binary);
		
	fin.read((char*)&temprec, sizeof(temp));
	while(fin)
	{
		
		cout << temprec[0].name << "   " << temprec[0].amnt << endl;

		fin.read((char*)&temprec, sizeof(temp));
	}

	fin.close();

	fin.open("trans.dat", ios::binary);

	
		
	fin.read((char*)&temprec, sizeof(temp));
	while(fin)
	{
		
		cout << temprec[1].name << "   " << temprec[1].amnt << endl;

		fin.read((char*)&temprec, sizeof(temp));
	}

	fin.close();


}

[Edited by - angelxe1 on December 7, 2004 7:53:46 AM]

Share this post


Link to post
Share on other sites
Advertisement
Since this is homework I won't solve it for you, but I will give you a pointer to where you're going wrong. Take a long hard look at this line:
 fout.write((char*)&master, sizeof(record));


Enigma

Share this post


Link to post
Share on other sites
lol
believe me when i say that i have looked at that one line for about two days but i still can't figure out what is wrong i want to write to the file master.dat and then open it and read the data into temprec -
anyway i tried to find something online about structs and i/o files - because i have no textbook since i couldn't afford it (it was either the text book which the teacher told us not to bother or the lab book which i needed) and i can not
does anyone have any links they can direct me two please?

Share this post


Link to post
Share on other sites
OK, I'll give you a bit more of a hint. You're saying that you manage to read the first record just fine, but not any of the other records. This leaves two possibilities:
  • You're not reading all the records properly

  • You're not writing all the records properly

Furthermore, if we dissect the line I highlighted earlier we can see a limited number of places that it could be going wrong:
fout.write((char*)&master, sizeof(record));
  • Is fout valid?

  • Is fout capable of writing data?

  • Is there a possibility of a bug in fout?

  • Is (char*)&master the data we want to write

  • Is the structure of master correct to allow us to write it out as an array of bytes?

  • Does sizeof(record) write out the number of items we want?


Enigma

Share this post


Link to post
Share on other sites
how do i know if i am writing the records properly? when i don't use binary i can just open it and look but this way i am not sure.

"Is fout valid?" it is writing the first record so i am assuming yes

"Is fout capable of writing data?" our teacher used fout in a similar program so i think yes

"Is there a possibility of a bug in fout?" a bug? i have no idea.

"Is (char*)&master the data we want to write?" i want to write the record called master to the file so yes (i think)

"Is the structure of master correct to allow us to write it out as an array of bytes?" home work:
------------------------- writing structures on disk --------------------------
14) This program deals with writing records (structures) on to a disk file. You will be using this file as input for the next program. Create the following structure in your program:

struct record
{
char name [15];
float amt;
};

Now set up 2 arrays of record structures, one called master and one called trans in the following manner:

struct record master [10];
struct record trans [7];

Initialize the two arrays with the folllowing data:

Master Trans

Helen 10. Lena 10.
Julie 20. Julie 5.75
Lena 30. Lee 15.02


"Does sizeof(record) write out the number of items we want?" it is supposed to, as far as i know.

i feel like i am where i started.

=(

Share this post


Link to post
Share on other sites
Keep going at it. I'm trying to help you learn how to debug, rather than just giving you the answer (the old "give a man a fish/teach a man how to fish" adage).

Quote:
how do i know if i am writing the records properly? when i don't use binary i can just open it and look but this way i am not sure.

You can still open the file using notepad or something similar, but any numbers in the file will show up as junk values. It can still be useful to try it though, as text will show up as normal.

Quote:
"Is fout valid?" it is writing the first record so i am assuming yes

To some extent this is a good assumption, however you can be more robust by checking the state of fout. Whenever you catch yourself making an assumption try to test that assumption as much as possible. In this case you might want to do a google search for "ofstream valid". The top few results there should give you some idea of how to check the state of fout.

Quote:
"Is fout capable of writing data?" our teacher used fout in a similar program so i think yes

fout is an instance of std::ofstream, which is the standard class for file output, so the answer to this question is indeed yes. Again, a quick google search for "ofstream" should be enough to confirm that std::ofstream is a class designed for writing to files.

Quote:
"Is there a possibility of a bug in fout?" a bug? i have no idea.

There are generally two possibilities when it comes to debugging - there is a problem in the code that is being called (in this case fout) or there is a bug in the code that is making the call (in this case your code). Since fout is a std::ofstream object from the standard library you can be 99.99999999% certain it does not contain any bugs. Therefore it must be your code that contains the bug.

Quote:
"Is (char*)&master the data we want to write?" i want to write the record called master to the file so yes (i think)

Indeed, although be careful of your terminology. master is an array of records, not a record. This is something you have to check yourself. Google can't help you. One step you can take to try and test this is to write the data to the screen just before you write it to the file to confirm its validity (I assume you've covered cout before ofstreams).

Quote:
"Is the structure of master correct to allow us to write it out as an array of bytes?" home work:
------------------------- writing structures on disk --------------------------
14) This program deals with writing records (structures) on to a disk file. You will be using this file as input for the next program. Create the following structure in your program:

struct record
{
char name [15];
float amt;
};

Now set up 2 arrays of record structures, one called master and one called trans in the following manner:

struct record master [10];
struct record trans [7];

Initialize the two arrays with the folllowing data:

Master Trans

Helen 10. Lena 10.
Julie 20. Julie 5.75
Lena 30. Lee 15.02

OK, this was a bit of a tougher one and depending on your level of experience you may not be able to answer it. Since it doesn't seem to be crucial to the homework I'll tell you that the structure of master is indeed correct to allow it to be written out as an array of bytes. I won't go into the details, since this has the potential to confuse more than it would probably help.

Quote:
"Does sizeof(record) write out the number of items we want?" it is supposed to, as far as i know.

Again, you've made an assumption. Try to verify it. Go through the maths explicitly. What is master? How big is it? What is a record? How big is it?

Enigma

Share this post


Link to post
Share on other sites
i went and retested some of the stuff before i read your last reply - and here is what i got so far -

the structs are being initialized properly (i used cout to confirm this)

fout is linked to ofstream which i did have in my original code sorry it was not included in this message.

sizeof(record) is returning the number 20. which according to me is supposed to be enough to at least write to lines. but all i see when i open the file is a bunch of binary then lena then more binary. (why is lena not in binary?)

i have been working on this for days. i'm just not getting this one thing and i can't move on from it.

Share this post


Link to post
Share on other sites
Consider the following:
#include <iostream>

struct SomeStruct
{
int memberVariable;
};

SomeStruct someStructs[10];

int main()
{
std::cout << "SomeStruct is " << sizeof(SomeStruct) << " bytes long\n";
std::cout << "someStructs is " << sizeof(someStructs) << " bytes long\n";
}





By the way, when I open master.dat in notepad I see: "Helen A", which is exactly what I would expect to see (although most of those spaces could be anything instead of just spaces - they're actually undefined).

Also, you have one insidious bug in your program which I will tell you about, because the likelihood of you finding it on your own is slim to none. When you close fin the status flags stay set, which means it still thinks it's at the end of the file, even after you open a new file. Insert a call to fin.clear() between fin.close() and fin.open("trans.dat", ios::binary);, or use two seperate ifstream objects.

Enigma

[Edited by - Enigma on December 1, 2004 10:31:41 AM]

Share this post


Link to post
Share on other sites
these are all things i kinda had a feeling about but just didn't know how to explain or where to go to from even in my own head. (the sizeof and the opening of files one after the other)

okay so i am not giving it enough space to write to. which is confusing because the teacher had this


struct student
{
char name[25];
int grade;
};

int main()
{
student s;
ofstream fout;
fout.open("test.dat", ios::binary);
// code to enter names and grades accordingly;

fout.write((char*)&s, sizeof(student));

// more code
}

why is it student in the sizeof? according to what i just saw from your message shouldn't be long enough to write to?

sorry to ask so much...

i made some changes and everything seems to fine now.
thank you so much for your help.

#include <iostream>
using namespace std;

#include <fstream>
using std::ofstream;
using std::ifstream;

struct record
{
char name[15];
float amnt;
};

struct temp
{
char name[15];
float amnt;
};


void main()
{
ofstream fout;

fout.open("master.dat", ios::binary);

record master [10] = {"Helen", 10, "Julie", 20, "Lena", 30,
"Alan", 40, "Annie", 50, "May", 60, "Lee", 70, "Sam", 80, "June", 90, "Bill", 100};

fout.write((char*)&master, sizeof(master));
fout.close();

fout.clear();

fout.open("trans.dat", ios::binary);

struct record trans [7] = {"Lena", 10, "Julie", 5.75, "Lee", 15.02,
"Ed", 40, "Art", 5.00, "Bill", 7.32};

fout.write((char*)&trans, sizeof(trans));
fout.close();

fout.clear();

temp temprec[10];
ifstream fin;
fin.open("master.dat", ios::binary);

fin.read((char*)&temprec, sizeof(temp));
while(fin)
{

cout << temprec[0].name << " " << temprec[0].amnt << endl;

fin.read((char*)&temprec, sizeof(temp));
}

fin.close();

fin.clear();

fin.open("trans.dat", ios::binary);



fin.read((char*)&temprec, sizeof(temp));
while(fin)
{

cout << temprec[0].name << " " << temprec[0].amnt << endl;

fin.read((char*)&temprec, sizeof(temp));
}

fin.close();


}



[Edited by - angelxe1 on December 7, 2004 7:45:19 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by angelxe1

record master [10] = {"Helen", 10, "Julie", 20, "Lena", 30,
"Alan", 40, "Annie", 50, "May", 60, "Lee", 70, "Sam", 80, "June", 90, "Bill", 100};

fout.write((char*)&master, sizeof(master));


That is one way of doing it, however consider this: master is an array of records. Now, we know that sizeof(record) is correct, and we know that master contains 10 records... think of the sizeof in another manner. For instance: "If you have 10 $50 bills, how much money do you have? How did you calculate that amount?" now lets rephrase that to match our question: "If you have 10 records, and each record is 20 bytes big, how big is it total?" The math for both is the same, and you might want to consider rewriting that fout to use sizeof(record) and account for that small bit of math.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!