-
Class as argument
Hello,
I would like to pass class as argument to/from a function which read/write to file.
I am a c++ novice and try some ways but no one works for me.
header:
Code:
#include <string>
class MyClass
{
public:
char FullName[40];
char CompleteAddress[120];
char Gender;
double Age;
bool mybool;
};
std::string filename="myJunk.dat";
int RWrecord (bool RW, long record, MyClass mc);
function in other file
Code:
#include <fstream>
#include <iostream>
#include <string.h>
#include <string>
#include <io.h>
using namespace std;
int RWrecord (bool RW, long record, MyClass)
{
MyClass mc;
if (RW) //read or write
{
ifstream ifs(filename.c_str(), ios::binary);
ifs.seekg (sizeof(mc)*record, ios::beg);
ifs.read((char*)&mc, sizeof(mc));
ifs.close();
}
else
{
ofstream ofs(filename.c_str(), ios::binary);
ofs.seekp (sizeof(mc)*record, ios::beg);
ofs.write((char*)&mc, sizeof(mc));
ofs.close();
}
return 0;
}
header is included in main file
from where I call function:
Code:
bool RW=false; //read
long record = 3;
int RWrecord (bool RW, long record, *MyClass)
//
// I would like class elements from record 3 here
but I get much errors during compiling.
Please help.
-
One way is to define a function template with the class type for the template parameter. However, I suggest that you overload operator<< and operator>> for the class instead, so that MyClass objects can be read and written with std::istream and std::ostream.
-
Thank you laserlight,
As a novice I need more concrete help to get this working with situation as presented.
When I have this code in my main function it works and I can read and write specific record to file.
But I have trouble when RWrecord is in other file.
And this is because I plan to use that function from more than one project.
-
I will stick with my recommendation of overloading those operators. You should also be wary of the use of those I/O operations that interpret the object as a stream of bits as that can fail to be correct when the class is not a POD type, or has pointer members.
-
You could include a forward declaration of the class in your cpp file. That should work but laserlight's idea is better although slightly more technical to implement.
-
Anyway, I still dont move forward with my example.
It seems I have more errors here.
In header bClass.h I have line:
Code:
std::string filename="myJunk.dat";
This header is included in my main file (main.cpp) and in my file with functions (bClass.cpp),
and compiler says:
Compiling: bClass.cpp
Compiling: Main.cpp
Linking console executable: bin\Release\aass.exe
obj\Release\Main.o:Main.cpp:(.bss+0x0): multiple definition of `filename'
obj\Release\bClass.o:bClass.cpp:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 10 seconds)
0 errors, 0 warnings
How is this possible and what to do to fix this?
-
The header file is being included for every #include "yourheader.h" you make.
This leads to multiple definitions of various things as a matter of course.
The way to stop this is to use the preprocessor to make something called an "include guard", which is just a conditional #define (based on whether it is defined or not). C++ does not emulate smarter modules in other languages. That is why you must do this.
-
I see.
Now I do this (I look to some example):
At top of header bClass.h I added:
Code:
#ifndef BCLASS_H
#define BCLASS_H
and at the end
But same happens.
Sure, filename is not defined nowhere else.
-
Do not use a global variable. If you really do want it, you could declare it as extern in the header and define it in exactly one source file, but from what I see it is unnecessary here, and so should be avoided.
-
Have you tried looking at where the compiler encountered it before? It did say it was encountered previously "here".
-
Hello Elysia,
No, I cannot locate where.
This is "build log" which dont offer any debug possibility, just text.
Interesting is that in build messages, which can show where is error I got this
||=== Build finished: 0 errors, 0 warnings ===|
But this is not correct,
because when I run a program they want to build again and again.
I use CodeBlocks IDE and here is possible such errors because CB is still under developing.
But I need CB because of usability in Windows and Linux.
Is here any possibility to attach a project?
-
I finally get solution which compiles well
header:
Code:
#ifndef BCLASS_H
#define BCLASS_H
class MyClass
{
public:
char FullName[40];
char CompleteAddress[120];
char Gender;
double Age;
bool myBool;
};
int RWrecord (bool RW, long record, MyClass *mc);
#endif //BCLASS_H
function file:
Code:
int RWrecord (bool RW, long record, MyClass *mc)
{
std::string filename="myJunk.dat";
if (RW)
{
std::ifstream ifs(filename.c_str(), std::ios::binary);
ifs.seekg (sizeof(mc)*record, std::ios::beg);
ifs.read((char*)&mc, sizeof(mc));
ifs.close();
}
else
{
std::ofstream ofs(filename.c_str(), std::ios::binary);
ofs.seekp (sizeof(mc)*record, std::ios::beg);
ofs.write((char*)&mc, sizeof(mc));
ofs.close();
}
return 0;
}
main:
Code:
int main()
{
std::string filename="myJunk.dat";
remove(filename.c_str());
bool RW;
long record;
MyClass one;
strcpy(one.FullName, "Row two");
strcpy(one.CompleteAddress, "My row two adress");
one.Gender = 'M';
one.Age = 3.14;
one.myBool = true;
record = 2;
RW = true;
int RWrecord (bool RW, long record, MyClass *one);
//-------------------------------------------------------------------
record = 2;
RW = false;
MyClass two;
int RWrecord (bool RW, long record, MyClass *two);
std::cout << "My Information\n";
std::cout << "My Name: " << two.FullName << std::endl;
std::cout << "Address: " << two.CompleteAddress << std::endl;
if(two.Gender == 'f' || two.Gender == 'F')
std::cout << "Gender: Female" << std::endl;
else if(two.Gender == 'm' || two.Gender == 'M')
std::cout << "Gender: Male" << std::endl;
else
std::cout << "Gender: Unknown" << std::endl;
std::cout << "Age: " << two.Age << std::endl;
return 0;
}
1 delete file if exist
2 fill data values to copy of class "one"
3 set RW to write and record to 2
4 call RWrecord to write data to record 2 (171 byte from beggining of file)
5 call RWrecord to read data from record 2 to new variable "two"
6 print data from variable two to console
Program compiles well
but my data dont passes correct
I assume that problem lies in my general missunderstanding of strings and pointers.
So please if someone could correct my code to get it to working condition.
Thanks.