change headerfile function prototypes into class prototype

the following program compiles and runs with no bugs. i am using this program to gradually learn the different features of c++. i read about things on ur site and then try them here. the hardest thing for me is understanding the relation between .h files and .cpp files. i want to put all of my functions in a class. i suppose i have to prototype the class in the header file, instead of prototyping the different functions? how? also, this may become complicated because i am having issues with the scope of the function PostOpenWrite, because it accepts ofstream& as a parameter. i suppose i should leave this function out of the class and just use it as is.

exportimportstructdec.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Grades
{
	int grade1;
	int grade2;
	int grade3;
	int grade4;
};

void PrintMemory(int ,Grades * );
void ScanStruct(Grades * );
void ReadFile(char [],Grades ,Grades * );
void WrtFile(char [],char [],Grades ,Grades * );
void AppFile(char [],char [],Grades ,Grades * );
Grades * Allocate(char [],Grades ,Grades *);



exportimportstructmain.cpp
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
#include <iostream>
#include <fstream>
#include "exportImportStructDec.h"
using namespace std;

Grades myGradesi,myGradeso,myGradesa;

//declare pointers to structures for file io:
Grades * pMyGradeso=&myGradeso;
Grades * pMyGradesa=&myGradesa;
Grades * pMyGradesi;

int main ()
{
	int choice;
	char opFile[]="binary.bin";
	char opMessage[]="\nplease enter 4 Grades separated by pressing enter\n";
	char menu[]="\ndo u want to \n1, read from the file, or \n2, write over the file or \n3, append the file or \n4, exit the program?\n";
	//give the user options:
	do
	{
		cout<<menu;
		cin>>choice;
		//option 1, read from the file:
		if (choice==1)
		{
			ReadFile(opFile,myGradesi,pMyGradesi);
		}
		//option 2, write over the file:
		if (choice==2)
		{
			WrtFile(opFile,opMessage,myGradeso,pMyGradeso);
		}
		//option 3, append the file:
		if (choice==3)
		{
			AppFile(opFile,opMessage,myGradesa,pMyGradesa);
		}
	//option 4, exit:
	}while (choice!=4);
	return 0;
}


exportimportstructdef.cpp
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
#include <iostream>
#include <fstream>
#include "exportImportStructDec.h"
using namespace std;


void PostOpenWrite(ofstream&,char [],Grades,Grades *);


void PostOpenWrite(ofstream& fileOpenWright,char openWriteMessage[],Grades structOpenWrite,Grades * pStructOpenWrite)
{
	cout << openWriteMessage;
	ScanStruct(pStructOpenWrite);
	if (fileOpenWright.is_open())
	{
		fileOpenWright.write (reinterpret_cast<char*>(pStructOpenWrite), sizeof(structOpenWrite));
		fileOpenWright.close();
	}
	else cout << "\nUnable to open file for output\n";
}


Grades * Allocate(char fileName[],Grades structAllocate,Grades * pStructAllocate)
{
	//check the size of the file and allocate appropriate memory:
	int firstBit,lastBit;
	ifstream fileAllocate (fileName);
	if (fileAllocate.is_open())
	{
		firstBit = fileAllocate.tellg();
		fileAllocate.seekg (0, ios::end);
		lastBit = fileAllocate.tellg();
		fileAllocate.close();
		int structsInFile=(lastBit-firstBit)/(sizeof(structAllocate));
		pStructAllocate = new Grades [structsInFile];
		return pStructAllocate;
	}
	else cout << "\nUnable to open file for size check\n";
}

//function to read all of the structures in a file, put them into memory, and display them on screen
void ReadFile(char readFileName[],Grades structi,Grades * pStructi)
{
	pStructi=Allocate(readFileName,structi,pStructi);
	//read the file into memory:
	int structArraySize=0;
	ifstream filei;
	filei.open (readFileName, ios::in|ios::binary);
	if (filei.is_open())
	{
		while ((filei.peek()!=EOF))
		{
			filei.read(reinterpret_cast<char*>(&pStructi[structArraySize]), sizeof(Grades));
			structArraySize++;
		}
		//display memory on screen:
		PrintMemory(structArraySize,pStructi);
	}
	else cout << "\nUnable to open file for input\n";
}

//function to write over a file with a new structure
void WrtFile(char wrtFileName[],char wrtMessage[],Grades structo,Grades * pStructo)
{
	ofstream fileo;
	fileo.open (wrtFileName, ios::out|ios::binary);
	PostOpenWrite(fileo,wrtMessage,structo,pStructo);
}

//function to append the end of a file with a new structure
void AppFile(char appFileName[],char appMessage[],Grades structa,Grades * pStructa)
{
	ofstream filea;
	filea.open (appFileName, ios::app|ios::binary);
	PostOpenWrite(filea,appMessage,structa,pStructa);
}

void ScanStruct(Grades * pStructScan)
{
	cin >> (*pStructScan).grade1 >> (*pStructScan).grade2 >> (*pStructScan).grade3 >> (*pStructScan).grade4;
}

void PrintMemory(int specificStructArraySize,Grades * pStructi)
{
	for(int i=0;i<specificStructArraySize;i++)
	{
		cout<<"\ngrade1\n"<< (pStructi[i]).grade1<<"\ngrade2\n"<< (pStructi[i]).grade2<<"\ngrade3\n"<< (pStructi[i]).grade3<<"\ngrade4\n"<< (pStructi[i]).grade4<<"\n";
	}
}







after i get most of the functions into a class and get a program that can compile,i will not be using a struct for file io anymore, instead i will use the class we create. i will work on using the new operator to allow the user to determine what type of and how many variables are in the class.
Last edited on
Generally you put the class definition in the header file (list its members, function prototypes, etc), and put the function bodies in a coresponding .cpp file. IE:

1
2
3
4
5
6
7
// test.h

class Test
{
public:
  void DoSomething();
};

1
2
3
4
5
6
7
8
//test.cpp

#include "test.h"

void Test::DoSomething()
{
  /* do something */
}


Any other cpp file can then use your 'Test' class by simply #including "test.h".

this may become complicated because i am having issues with the scope of the function PostOpenWrite, because it accepts ofstream& as a parameter


This makes ofstream a dependency.

1
2
3
4
5
6
7
8
9
// test.h

#include <iosfwd>

class Test
{
public:
  void foo(std::ofstream& astream);
};

1
2
3
4
5
6
7
8
// test.cpp
#include <fstream>
#include "test.h"

void Test::foo(std::ofstream& astream)
{
  astream << "bar";
}


Although -- it makes more sense to take ostream instead of ofstream, unless you're using file specific stuff. Best to use the class highest in the hierarchy unless you need the specialization.

For further info on headers/source files/making it all work -- I wrote this article on it you might want to check out:

http://cplusplus.com/forum/articles/10627/


EDIT -- gah crap my fstream example won't work because of template and namespace issues -- gimmie a sec to sort this out

EDIT 2 - okay that ought to fix it. I need to look up how to forward declare typedefed templates, that's something that's been bugging me.
Last edited on
thank you very much, ill get to work making these changes and then read your article
thanks again, your article cleared up quite a bit of confusion for me
well things were going swimmingly until i changed all my char[] into string, what im doing should make sense yes?

exportimportstructdec.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iosfwd>
#include <iostream>
#include <fstream>
#include <string>

class BinFileIO
{
	void PrintMemory();
	void PostOpenWrite(std::ofstream&,string::string&);
	void ScanStruct();
	public:
	void ReadFile(string::string&);
	void WrtFile(string::string&,string::string&);
	void AppFile(string::string&,string::string&);
	int grade1;
	int grade2;
	int grade3;
	int grade4;
};

exportimportstructdef.cpp
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
#include "exportImportStructDec.h"
using namespace std;




void BinFileIO::PostOpenWrite(ofstream& fileOpenWright,string openWriteMessage)
{
	cout << openWriteMessage;
	this->ScanStruct();
	if (fileOpenWright.is_open())
	{
		fileOpenWright.write (reinterpret_cast<char*>(this), sizeof(*this));
		fileOpenWright.close();
	}
	else cout << "\nUnable to open file for output\n";
}
void BinFileIO::ReadFile(string readFileName)
{
	ifstream filei;
	filei.open (readFileName, ios::in|ios::binary);
	if (filei.is_open())
	{
		filei.read(reinterpret_cast<char*>(this), sizeof(BinFileIO));
		this->PrintMemory();
	}
	else cout << "\nUnable to open file for input\n";
}

//function to write over a file with a new structure
void BinFileIO::WrtFile(string wrtFileName,string wrtMessage)
{
	ofstream fileo;
	fileo.open (wrtFileName, ios::out|ios::binary);
	this->PostOpenWrite(fileo,wrtMessage);
}

//function to append the end of a file with a new structure
void BinFileIO::AppFile(string appFileName,string appMessage)
{
	ofstream filea;
	filea.open (appFileName, ios::app|ios::binary);
	this->PostOpenWrite(filea,appMessage);
}

void BinFileIO::ScanStruct()
{
	cin >> this->grade1 >> this->grade2 >> this->grade3 >> this->grade4;
}

void BinFileIO::PrintMemory()
{
	cout<<"\ngrade1\n"<< this->grade1<<"\ngrade2\n"<< this->grade2<<"\ngrade3\n"<< this->grade3<<"\ngrade4\n"<< this->grade4<<"\n";
}

exportimportstructmain.cpp
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
#include "exportImportStructDec.h"
using namespace std;

BinFileIO myGradesi,myGradeso,myGradesa;

//declare pointers to structures for file io:
BinFileIO * pMyGradeso=&myGradeso;
BinFileIO * pMyGradesa=&myGradesa;
BinFileIO * pMyGradesi;

int main ()
{
	BinFileIO objectBinIO;
	int choice;
	string opFile;
	string opMessage="\nplease enter 4 Grades separated by pressing enter\n";
	string menu="\ndo u want to \n1, read from the file, or \n2, write over the file or \n3, append the file or \n4, exit the program?\n";
	//give the user options:
	do
	{
		cout<<"please enter the file name";
		cin>>opFile;
		cout<<menu;
		cin>>choice;
		//option 1, read from the file:
		if (choice==1)
		{
			objectBinIO.ReadFile(opFile);
		}
		//option 2, write over the file:
		if (choice==2)
		{
			objectBinIO.WrtFile(opFile,opMessage);
		}
		//option 3, append the file:
		if (choice==3)
		{
			objectBinIO.AppFile(opFile,opMessage);
		}
	//option 4, exit:
	}while (choice!=4);
	return 0;
}
string::string is not the correct way to declare a string variable.
i tried just "string" and "string&" and "string::string&" and "string::string" and nothing works
i got it i had to use std namespace in the header file
Topic archived. No new replies allowed.