Structure In Binary File I/O

Hello,
I'm trying to insert a structure into a binary file, then read it back out into a "temporary" structure and output some values.

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
#include <iostream>
#include <fstream>

using namespace std;

struct b_tree_node {

  int  num_keys;      // number of keys in this node
  int  key_val[3];    // key values (0 to num_keys - 1)
  int  child[4];      // child file addresses (0 to num_keys)
                      // [record index, not byte address]
  // may need filler to force zeros in any padding of the struct
  } ;

	int main()
	{
		int val ;
		b_tree_node * temp = new b_tree_node;   // Original node
		b_tree_node * temp2 = new b_tree_node;  // New node

		temp->key_val[0] = 12 ;
		temp->key_val[1] = 24 ;
		temp->key_val[2] = 36 ;
		temp->key_val[3] = 48 ;

		fstream myFile ( "test1.bin" , ios::in | ios::out | ios::binary ) ;

		if (!myFile) {
			cout<<"Unable to open file!" << endl ;
			return 1;
		}
        myFile.write(( char *) temp , sizeof (temp) ) ;

        myFile.read ( (char*) temp2 , sizeof(temp2) ) ;

        cout << temp2->key_val[0] << endl ;

		myFile.close() ;
		return 0;
	}


Can anyone tell me what I've done wrong?
Thanks!
Joshua Schweigert wrote:
Can anyone tell me what I've done wrong?
- You created a new topic when you already had this one: http://www.cplusplus.com/forum/general/126798/
- Line 4
- You've used C++ as if it were C.
- You're abusing pointers and dynamic memory for no reason on lines 18 and 19
- Line 24 accesses out-of-bounds index
- You open the file for both read and write on line 26
- You use the wrong condition to see if the file opened on line 28
- You write pointers instead of the structure on lines 32 and 43
- You explicitly call .close() on line 38
Last edited on
Well if I can understand insertion of a struct into a binary file then I wont need that other question open now would I?

I just love it when programmers like yourself think that just because you know more than the next guy that you can act like an asshole towards them.

I'm sorry I need help and that I dont understand some things? I guess its a crime on this website because you're the 4th person to do it.

Dont bother commenting again unless its actually useful because all you've done is nag me about things that actually are fine the way they are.

Good day asshole.
My post was in no way intended to be rude, I'm sorry you got that impression. If you'd like to ignore my advice/criticism because it offends you, I'll stop repying to this thread.

EDIT: http://www.cplusplus.com/forum/general/126798/#msg689953
Since you asked nicely, I will now stop helping you permanently.
Last edited on
closed account (N36fSL3A)
Are you getting compiler errors? If so can you please post them so people can help?

I pretty much agree with LB except for his last point. You also did not free allocated memory (try delete).

If you want to re-read the written structure, then insert this
myFile.seekg(0, std::ios::beg);
before you read the structure.

1
2
3
4
5
6
7
8
struct b_tree_node {

  int  num_keys;      // number of keys in this node
  int  key_val[3];    // key values (0 to num_keys - 1)
  int  child[4];      // child file addresses (0 to num_keys)
                      // [record index, not byte address]
  // may need filler to force zeros in any padding of the struct
  } ;
You should not be hard-coding supposedly dynamic data like that.

I highly recommend you read this article:
http://www.cplusplus.com/articles/DzywvCM9/
_________________________________

Joshua Schweigert wrote:
I just love it when programmers like yourself think that just because you know more than the next guy that you can act like an asshole towards them.
I can see where this is coming from, it isn't uncommon for programmers to act cocky, however LB was not trying to act that way.

Do not respond with rudeness when someone is trying to give you helpful criticism. He's trying to help you get rid of bad habits that can bite you later.
Last edited on
I dont really see how him responding, to my question of what I've done wrong, with a link to another thread I opened isnt rude. So if he responds with a rude comment I will respond with a rude comment as well. I wouldnt be so edgy on this shit but I've been trying to figure it out for the past 2 weeks to no avail so its pretty frustrating when someone responds with useless information.

The way I wrote it is the way I saw on countless other examples that I was trying so for him to tell me its all wrong without hinting at a way to correct it doesnt seem like hes trying to help at all, it seems like hes just trying to nit pick at my stuff just to be that guy.
closed account (N36fSL3A)
Joshua Schweigert wrote:
The way I wrote it is the way I saw on countless other examples that I was trying so for him to tell me its all wrong without hinting at a way to correct it doesnt seem like hes trying to help at all, it seems like hes just trying to nit pick at my stuff just to be that guy.
Well you did ask "What am I doing wrong?", that's a pretty vague question.

Anyway, did you solve it or not? Can you answer the questions I've asked in my previous post?
I do not get compiler errors, heres the code after adding your reccomendation before reading the structure:

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

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct b_tree_node
  {
  int  num_keys;      // number of keys in this node
  int  key_val[3];    // key values (0 to num_keys - 1)
  int  child[4];      // child file addresses (0 to num_keys)
                      // [record index, not byte address]
  // may need filler to force zeros in any padding of the struct
  };

int main (int argc, char* argv[]){
     b_tree_node * temp = new b_tree_node ;
     b_tree_node * temp2 = new b_tree_node ;

     temp->key_val[0] = 32 ;
     temp->key_val[1] = 48 ;
     temp->key_val[2] = 59 ;

    fstream myFile ( "test1.bin" , ios::in | ios::out | ios::binary ) ;
    if(!myFile) {

        cout << "Error opening file\n" ;
        return 1 ;

    }

     myFile.write ( ( char * ) temp , sizeof ( b_tree_node ) ) ;
     myFile.seekg(0, ios::beg);
     myFile.read ( ( char * ) & temp2 , sizeof ( b_tree_node ) ) ;

     cout << temp2->key_val[0] << endl ;
     cout << temp2->key_val[1] << endl ;
     cout << temp2->key_val[2] << endl ;

     myFile.close() ;

    return 0;
}



It outputs a random value and two zeros then crashes.
closed account (N36fSL3A)
myFile.read ( ( char * )temp2 , sizeof ( b_tree_node ) ) ;

Although I still highly recommend you free memory after you allocate it (In this instance, you shouldn't even be allocating on the heap; only do so when it's required) try replacing the read line with that one.

You're technically reading the address of a pointer in, which is giving you garbage.
Thank you, it is working now.

What did you mean by
"You should not be hard-coding supposedly dynamic data like that."
I'm not sure I know what you mean.

Also, are you saying I need to use
delete myFile

Or delete the original structure temp ?

Thanks for all your help thus far!
closed account (N36fSL3A)
Joshua Schweigert wrote:

Also, are you saying I need to use
delete myFile

Or delete the original structure temp ?

Thanks for all your help thus far!
Well I am saying delete all pointers.

"You should not be hard-coding supposedly dynamic data like that."
I'm not sure I know what you mean.
Oh, just ignore that.
Okay thank you so much!

So now the question is how do I write multiple structures and read them. Do I need to use seekg ? I guess this is the new confusing part for me.
closed account (N36fSL3A)
Depends on how you want to do it.

Here's an example (Not based off of your source, but you should be able to modify it to your needs):

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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib> // For random number generator. You don't need this for your purposes.
#include <ctime>   // For random number generator. You don't need this for your purposes.

struct MyStructure
{
	unsigned int  data;
	unsigned int  random;
};

int main()
{
	unsigned int i = 0;
	
	std::vector<MyStructure> structs;
	std::ifstream in;
	std::ofstream out;
	
	srand(time(nullptr));
	
	// Read hardcoded data
	std::cout << "Hardcoded data :\n";
	for(i = 0; i < 10; i++)
	{
		MyStructure tmp = {};
		
		tmp.data = 10;
		tmp.random = rand() % 50; // Generate a random number;
		
		std::cout << " Structure " << i << "\n";
		std::cout << " Data: " << tmp.data << "\n";
		std::cout << " Random: " << tmp.random; "\n";
		
		structs.push_back(tmp); // Add it to vector
	}
	
	out.open("ex.txt");
	out.write(reinterpret_cast<const char*>(&structs[0]), sizeof(MyStructure) * 10);
	out.close();
	in.open("ex.txt");
	in.read(reinterpret_cast<char*>(&structs[0]), sizeof(MyStructure) * 10);
	in.close();
	
	// Display data that was read
	std::cout << "\nRead-in data :\n";
	for(i = 0; i < 10; i++)
	{
		std::cout << " Structure " << i << "\n";
		std::cout << " Data: " << structs[i].data << "\n";
		std::cout << " Random: " << structs[i].random; "\n";
	}
	
	std::cin.get();
	
	return 0;
}


I'm going to post it here again in-case you've missed it.

I highly recommend you read this article:
http://www.cplusplus.com/articles/DzywvCM9/
Topic archived. No new replies allowed.