I want to pass in constructor mode of file - c++

I created child class of ofstream. I want to pass in constructor mode of file. For example ios::app. How can i do it ? What should i write in my_file constructor to put it in ofstream class constructor? I know that it's int type but how to understand what is value of ios::app?
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
class my_file : public ofstream {
string name;
public:
my_file(string name, const char* filename) : ofstream(filename) { this->name = name; }
inline const string get() { return this->name; }
};
int main(void) {
my_file file("Name","new.txt" /* , ios::app */ );
return 0;
}

I know that it's int type but how to understand what is value of ios::app?
Wrong, that's not a int!
Go to ofstream doc http://www.cplusplus.com/reference/fstream/ofstream/, then click (constructor) to see what the parameters are and then you can see that mode is of type std::ios_base::openmode (as described here)
So simply do:
class my_file : public ofstream {
string name;
public:
my_file(string name, const char* filename, std::ios_base::openmode mode ) : ofstream(filename,mode) { this->name = name; }
inline const string get() { return this->name; }
};
Then:
my_file file("Name","new.txt", ios::app);

Related

Struct having pointer to member in C++, How to access it

OK here is my code. I have struct named employee and it has a member char* name. How do I change the value of name?
struct employee {
char* name;
int age;
};
int main()
{
struct employee james;
james.age=12; // this line is fine
james.name = "james"; // this line is not working
cout << james.name;
return 0;
}
Use std::string instead of char* pointer, it will work fine
#include <iostream>
#include <string>
struct employee {
std::string name;
int age;
};
int main() {
employee james;
james.age=12;
james.name = "james";
std::cout << james.name;
return 0;
}
Or
If you want to use char* pointer then use const char* name it will work.
#include <iostream>
struct employee {
const char* name;
int age;
};
int main() {
employee james;
james.age=12;
james.name = "james";
std::cout << james.name;
return 0;
}
Any literal string value you enter into your source code (such as "james") is by definition a const char* value, the const meaning it may not be altered at program runtime. In your class the name member is declared to be of type char* which is not const and so may be altered at runtime. Your compiler does not allow you to assign a const char* value to a variable of type char* to maintain the invariant that a value of type const char* may not be modified. (The other way around is fine of course; you may assign a char* value to a variable of type const char*.
To fix this with the fewest characters, you must change char* name to const char* name in your employee struct definition. However, I agree that the best thing to do is change it to a std::string member as #Hamza.S laid out in their answer. The std::string class has an assignment operator that builds it out of a const char* value, so the line james.name = "james" in their answer essentially sets the std::string equal to the const char* value "james".
If you are keen on using char*, you could do something like this :
#include <iostream>
#include <string.h>
#include <stdlib.h>
struct employee {
char *name;
int age;
};
int main() {
employee james;
james.age=12;
james.name = (char *)malloc(sizeof(char) * 10);
strcpy(james.name, "James");
std::cout << james.name << std::endl;
return 0;
}
Or else you could use std::string in your struct like this :
#include <iostream>
#include <string>
struct employee {
std::string name;
int age;
};
int main() {
employee james;
james.age=12;
james.name = "james";
std::cout << james.name;
return 0;
}
You can try using strcpy
strcpy(james.name, "james");

Creating objects from another class and adding them to an Array [C++]

I'm new to C++ and stuck on a problem. I want class Admin to be able to create new objects of the Student class and add the objects to an array that contains all students' info. How can I do that in the Admin class?
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Student
{
public:
int SSN_LENGTH = 9, MIN_NAME_LEN = 1, MAX_NAME_LEN = 40;
string DEFAULT_NAME = "no name", DEFAULT_SSN = "000000000";
private:
string studentName, SSN;
public:
// constructor declarations
Student();
Student( string studentName, string SSN);
// Accessors
string getSSN(){ return SSN; }
string getStudentName(){ return studentName; }
// Mutators
bool setSSN(string SSN);
bool setStudentName(string studentName);
};
class Admin
{
private:
static const int Student_MAX_SIZE = 100000;
public:
bool addStudent (string studentName, string SSN);
};
How can I do that in the Admin class?
Use std::vector, illustrated by the code below:
#include <vector>
//...
class Admin
{
private:
static const std::size_t Student_MAX_SIZE = 100000;
std::vector<Student> vStudent;
public:
bool addStudent (string studentName, string SSN)
{
if ( vStudent.size() < Student_MAX_SIZE )
{
vStudent.push_back(Student(studentName, SSN));
return true;
}
return false;
}
};

std::sting ? string does not name a type error

I got these 2 files for now and anytime I want to compile I get the error
string does not name a type
in Bestellung.h on the line with std::string name;.
Why?
main.cpp
#include "Bestellung.h"
#include <iostream>
using namespace std;
int main()
{
Bestellung();
cout << Bestellung{"maki"} << endl;// [maki,10€]
}
Bestellung.cpp
#include "Bestellung.h"
Bestellung(string bestellV, double preisV = 10){
name = "bestell V";
preis = "preis V";
};
string get_name const(Bestellung v) {
return Bestellung.name;
};
double get_preis const(Bestellung v){
return Bestellung.preis;
};
ostream& print(ostream&) const {
};
Bestellung.h
#ifndef BESTELLUNG_H
#define BESTELLUNG_H
#include <string>
#include <iostream>
class Bestellung{
std::string name;
std::double preis;
public:
Bestellung(string, double = 10);
string get_name const {
};
double get_preis const {
};
ostream& print(ostream&) const {
};
};
#endif
You have to use a namespace qualifier. You have:
Bestellung(string,double=10);
You should have:
Bestellung(std::string,double=10);
You also have:
string get_name const {
You should have:
std::string get_name const {
If you don't want to specify the std namespace every time you use a string, you can do this near the beginning:
using std::string;
Doing that in header files is bad practice though, so I would just use the full qualifications like I said to first.
After correcting this error, you need to do the same thing to that ostream you have too.
Read more about namespaces here.

C++, Access violation

I have started to learn C++ some weeks ago and now I have a problem with my current project.
I wanted to write templates, that allow me to save objects into binary datas and load them again later. Here ist the code of these templates:
#ifndef TOOLS_H
#define TOOLS_H
#include <fstream>
#include <string>
namespace Tools
{
template <class T>
void writeBinaryFile(std::string filename, T object)
{
std::ofstream of(filename, std::ios::out | std::ios::binary);
of.write((char*) &object, sizeof(T));
of.close();
}
template <class P>
P readBinaryFile(std::string filename)
{
P temp;
std::ifstream ifs(filename, std::ios::in | std::ios::binary);
ifs.read((char*) &temp, sizeof(P));
ifs.close();
return temp;
}
}
#endif
I created a class called GameSettings. The header data is:
#ifndef GAMESETTINGS_H
#define GAMESETTINGS_H
#include <iostream>
#include <string>
#include "SFML\Graphics.hpp"
class GameSettings
{
public:
GameSettings();
GameSettings(std::string playerName, bool sound, int volume, int level);
~GameSettings();
void setPlayerName(std::string playername){ playerName = playername; };
void setSound(bool sound){ this->sound = sound; };
void setVolume(int volume){ this->volume = volume; };
void setLevel(int level){ this->level = level; };
const std::string getPlayerName() { return playerName; }
const bool getSound() { return sound; }
const int getVolume() { return volume; }
const int getLevel() { return level; }
private:
std::string playerName;
bool sound;
int volume;
int level;
};
#endif
With the cpp-data:
#include "GameSettings.h"
GameSettings::GameSettings(std::string playerName, bool sound, int volume, int level)
{
this->playerName = playerName;
this->sound = sound;
this->volume = volume;
this->level = level;
}
GameSettings::GameSettings():
playerName(""),
sound(true),
volume(0),
level(0)
{
}
GameSettings::~GameSettings()
{
}
When I start the main-function:
#include <iostream>
#include "GameSettings.h"
#include "Tools.h"
int main()
{
GameSettings* gs = new GameSettings("Andrew", true, 100, 3);
Tools::writeBinaryFile<GameSettings>("gamesettings.bin", *gs);
gs->setPlayerName("TEST");
*gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");
std::cout << gs->getPlayerName();
std::getchar();
return 0;
}
an error occurs:
Unhandled exception at 0x5a1cad54 (msvcp100d.dll) in Mohrhuhn.exe: 0xC0000005: Access violation writing location 0xfeeefeee.
Can somebody help me?
Sincerly, Andrew
I think the root of the trouble is
*gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");
You read raw bytes to a variable that contains std::string. It may ruin char pointer inside it. So, any call to playerName should fail or result in UB.
Only POD types can be read/write this way. A bit more I found on another web-page: http://www.cplusplus.com/forum/general/39764/
The template you implement to serialize the object will not work because casting the std::string to char* and saving sizeof(std::string) will not save the content of the string.
Check the saved file, but I guess you need to implement properly serialization and deserialization.
First of all writing down binary files by just dumping them from memory is a bad idea since you might incur in lots of additional problems (e.g. shallow copies, polimorphism, etc..)
return temp;
You are returning a temporary object that is being destroyed after the function exits.
Change your code into
gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");
...
template <class P>
P* readBinaryFile(std::string filename)
{
P* temp = new P();
std::ifstream ifs(filename, std::ios::in | std::ios::binary);
ifs.read((char*) temp, sizeof(P));
ifs.close();
return temp;
}
and everything will work out properly (psst. remember to free the memory!)

No matching constructor for initialization of

I’ve seen similar questions on StackOverflow, but none of them seems to apply to me.
Here is my code:
Option.cpp
#include "Option.h"
Option::Option(string valueName, string description, OptionType type){
this->valueName = valueName;
this->description = description;
this->type = type;
};
Option.h
#include <iostream>
using namespace std;
enum OptionType { FLAG, REQUIRED, NORMAL };
class Option {
string valueName, description, value;
OptionType type;
public:
Option(string valueName, string description, OptionType type);
void setValue(string value) {
this->value = value;
};
string getValueName() {
return this->valueName;
};
string getDescription() {
return this->description;
};
OptionType getType() {
return this->type;
};
};
Options.cpp
#include "Options.h"
using namespace std;
Options::Options(int _argc, const char * _argv[]) : argv(_argv) {
this->argc = _argc;
}
Options::~Options() {
options.~unordered_map();
}
void Options::printHelp() {
for (auto &i : options) {
cout << i.first << '\t' << i.second.getDescription() << '\n';
}
}
void Options::addFlag(string flagName, string description) {
}
void Options::addOption(string optionName, string valueName, string description, OptionType type) {
Option option(valueName, description, type);
options[optionName]=option;
}
void Options::addOptionAlias(string aliasName, string optionName) {
}
Options.h
#include <iostream>
#include <unordered_map>
#include "Option.h"
using namespace std;
class Options {
unordered_map<string, Option> options;
int argc;
const char ** argv;
public:
Options(int argc, const char * argv[]);
~Options();
void parse();
void addOption(string optionName, string valueName, string description, OptionType type);
void addFlag(string flagName, string description);
void addOptionAlias(string aliasName, string optionName);
void getOption(string optionName);
void printHelp();
};
It's in options.cpp on the line Option option(valueName, description, type); that the error seems to stem from, but for the life of me, I can’t figure out why. As far as I can see, the constructor in Option takes the right types.
The problem is actually in the next line:
options[optionName]=option;
That first calls the operator[] in the map, that searchs for the given key and returns the associated value. If the key is not found, it insert a default initialized value connected to that key. Then this value is copy assigned with your option.
Do you see the problem? Your Option class does not have a default constructor, so it cannot be default initialized! Read carefully your error message, surely it is talking about the default constructor, not the one you are looking at.
You have several solutions. The easiest would be to write a default constructor for your class.
The alternative would be never to use operator[] in the map so that the default constructor is never needed. If that's what you want to do, to insert an item you write:
options.insert(std::make_pair(optionName, option));
Finally, if you are using C++11 (or later) and a compliant enough compiler, you can even build the object directly into the container: zero copy overhead and you don't even need the copy constructor!
options.emplace(std::piecewise_construct,
std::forward_as_tuple(optionName),
std::forward_as_tuple(valueName, description, type));
There's a mismatch between the declaration of the constructor in the header and the definition in the source file.
In header...
Option(string& valueName, string& description, OptionType& type);
In source file...
Option::Option(string valueName, string description, OptionType type){
Notice the parameters are defined as references (e.g., string&) in the header, but as objects (e.g., string) in the source.