Send to class char array defined in header - c++

The issue that I am having is that I am trying to build a DLL. And I am using char instead of strings to store information.
I have defined the following in the header file:
class Test{
public:
int qLenght;
char firstName[];
char surName[];
};
I am having problems inputting codes from the main program using the following:
int main()
{
Test theTest;
theTest.firstName[0] = {"Mike Smith","Jonny Vegas","Jimmy Woo"};
}
I have included the header code at the top of my main project.
It won't let me add to the char array. This may seem like a stupid question but I am struggling and hopefully someone can shed some light as to where I am going wrong. Am I missing a parameter?

Your class needs to know how much memory to allocate when you instantiate the class (which is not the same time as you assign the values).
class Test
{
public:
char firstName[2][100];
};
int main()
{
Test theTest;
strcpy(theTest.firstName[0], "Mike Smith");
strcpy(theTest.firstName[1], "Jonny Vegas");
return 0;
}
Alternatively, you can allocate memory for the strings dynamically at the time of assignment, but then you need to remember to free it again:
class Test{
public:
char *firstName[2];
};
int main()
{
Test theTest;
theTest.firstName[0] = strdup("Mike Smith");
theTest.firstName[1] = strdup("Jonny Vegas");
// do stuff
free(theTest.firstName[0]);
free(theTest.firstName[1]);
return 0;
}

Related

Problem: Create dynamic arrays in a class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm writing a student administration program right now. I would like to do without strings and libraries to learn how to use pointers. Each student has a name, a number and several courses. I manage this data of the student in a class. Names and courses should only occupy as much space as is absolutely necessary. However, I do not know exactly how to initialize them correctly and create the constructors, setters or getters. Later, I want to manage the Student class in a class with an array of students.
I've already tried managing the char array of courses in an additional array. I did not succeed. That's why I've created a two-dimensional array now. I also came up with the idea to create extra classes for the courses and the array of courses. But that's not how I learn how to handle pointers.
student.h:
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
class Student{
private:
int myLength_name;
char *myName; //=new char[myLength_name];
int myMatrikel;
int myLength_lv;
char *myLv; //=new char[myLength_lv];
//char **myLvs[30];
int myAnzLv;
public:
Student();
Student(char *name_chars, int length_name, int matrikel, int length_lv, char **lv_chars[][30]);
char &name_chars() const { return *myName; }
int matrikel() const { return myMatrikel; }
int length_name() const { return myLength_name; }
int length_lv() const { return myLength_lv; }
char &lv_chars() const { return *myLv; }
};
#endif // STUDENT_H
student.cpp:
Student::Student() :
myLength_name(0),
myName(nullptr),
myMatrikel(0),
myLength_lv(0),
myLv(nullptr),
myAnzLv(0)
{}
Student::Student(char *name_chars, int length_name, int matrikel, int length_lv, char *lv_chars[][30]):
myLength_name(length_name),
myName(name_chars=new char[myLength_name]),
myMatrikel(matrikel),
myLength_lv(length_lv),
myLv(lv_chars=new char[myLength_lv][30]),
{}
Can someone please help me create the class student error free? I'm really not very good with pointers and have not found helpful manuals so far.
Thanks in advance.
Eric
#MPops
Thank you very much for your help. I hope I implemented your code right. The two files now look like this and they don't produce errors:
student.h:
class Student{
private:
char *myName;
int myMatrikel;
char *myLv; //=new char[myLength_lv];
char * * myLvs = new char*[30];
int myAnzLv;
public:
Student();
Student(char *name_chars, int matrikel, char *lv_chars);
char name_chars() const { return *myName; }
int matrikel() const { return myMatrikel; }
char lv_chars() const { return *myLv; }
};
student.cpp:
Student::Student() :
myName(nullptr),
myMatrikel(0),
myLv(nullptr),
myLvs(nullptr),
myAnzLv(0)
{}
Student::Student(char *name_chars, int matrikel, char *lv_chars):
myMatrikel(matrikel)
{
myName = new char[strlen(name_chars)+1];
strcpy(myName, name_chars);
myLv = new char[strlen(lv_chars)+1];
strcpy(myLv, lv_chars);
}
````
When creating a class that has a char pointer (to be used as a dynamic char array), I don't believe you will be able to use the initialization list feature of the constructor. You should first verify that it works simply by...
myName = new char[strlen(name_chars)+1];
strcpy(myName, name_chars);
This is the most basic way to do this. It's not particularly safe though, if for some reason the data doesn't come in correctly (no \0 character in name_chars). But this is a start.
I would also look into strncpy.
To make an ARRAY of dynamic char arrays...
like ["math", "language", "writing", "history"]...
You need an array of dynamic char arrays.
char * course = new char[100]; // this is one char array of length 100.
char * * courses = new char*[10]; // this is 10 char pointers
courses[0] = new char[100]; // now, the first char pointer in courses
// is a dynamic array of length 100.
...
courses[9] = new char[100];
courses[10] = new char[100]; //!!!! THIS IS WRONG. Courses doesn't have 11 items in it.
// you can only use indexes 0-9 (10 char pointers)

How can I pass arguments to a class by creating an object in C++?

I am working on my first separate class file. I have been given a driver program which I am not supposed to change and I am to create a class file that runs off the driver.
#include <iostream>
#include <iomanip>
using namespace std;
#include "Question.h"
int main()
{
string q2Answers [] = {"China","India","Mexico","Australia"};
Question q2("Which country is home to the Kangaroo?",q2Answers,'D');
q2.display();
cout << endl;
}
The driver, simplified above, appears to be passing arguments to the class via arguments. My class header file is built in the following fashion.
#ifndef QUESTION_H
#define QUESTION_H
#include <string>
using namespace std;
class Question
{
public:
void setStem(string newStem);
void setAnswers(string newAnswers[]);
void setKey(char newKey);
void display();
string getStem();
string getAnswer(int index);
char getKey();
private:
string stem;
string answers[4];
char key;
};
#endif // QUESTION_H
How can I execute the functions in my class using arguments passed into an object? I am confused as to how the line,
Question q2("Which country is home to the Kangaroo?",q2Answers,'D');
has any way of pushing those arguments into the functions. Any insight into this would be very appreciated.
If I understood you correctly, you're asking for how to make a constructor(See OldProgrammer's link in the comment to your question):
You can either make it right in the header file, like so:
Question(const std::string& theQuestion,
const std::string theOptions[], const char& correctAnswer)
{
this->stem = theQuestion;
for(int i=0; i<4; i++){
this->answers[i] = theAnswers[i];
}
this->key = correctAnswer;
}
~Question(){}
//This is called the "Destructor", it is a function called when the object is destroyed
(You can imagine the const std::string&-part as string or const char&-part as just char if you don't know what they mean, since it's not very important right now.)
Or you can make it in the separate .cpp-file like so:
Question::Question(const std::string& theQuestion,
const std::string& theOptions[], const char& correctAnswer)
{
this->stem = theQuestion;
for(int i=0; i<4; i++){
this->answers[i] = theAnswers[i];
}
this->key = correctAnswer;
}
Question::~Question(){}
You might be asking why we use destructors; it's because sometimes there are things we need to do before the object is removed.
Like for instance if you want to save certain info or make a change, or more commonly to free dynamic memory you allocated when you made the object. Otherwise you get memory leaks, which are bad.
Then you can construct/create an object as such:
Question q2("Which country is home to the Kangaroo?",q2Answers,'D');
You can also "overload" the constructor, i.e. you can make other versions of it. For example if you imagine that the constructor's only parameter was the question:
Question(std::string q){
this->stem = q;
}
Question(char c[]){
this->stem = c;
}
Now you can pass either a string or an array of characters to the object. But if you only have one, you can't do the other too, so if we only have the first constructor, we can't pass an array of characters to do the exact same thing. And you can make as many of these as you like, but it doesn't necessarily mean that it's better just because it has a ton of constructors.

How to make a quiz database using C++

/This is just the a part of the code that makes the database. Random access to questions will be generated in the same main function. What is wrong in this code? Please take a look and help/
#include<iostream>
#include<cstring>
class ques{
void in_data(char qu[500],char p[25],char q[25],char r[25],char s[25],char ans1)
{
std::strcpy(question,qu);
std::strcpy(a,p);
std::strcpy(b,q);
std::strcpy(c,r);
std::strcpy(d,s);
ans=ans1;
}
};
int main()
{
ques q[2];
q[0].in_data("what is 2+2","alpha","beta","gamma","delta","d");
q[1].in_data("choose a","a","b","c","d","a");
return 0;
}
there are many errors in your code:
1- make in_data() public to be able to call it from outside like in your main otherwise you get compile-time error accessing private data remember members of a class is by default private whereas struct's are public
2- declare member data: question, a, b,... you are using them without declaring them.
3- you declared in_data to take a character as the sixth parameter while you pass to it a const character string in main:
q[0].in_data("what is 2+2","alpha","beta","gamma","delta","d"); // "d" is a constant character string not just a single character so change it to 'd'
q[1].in_data("choose a","a","b","c","d","a"); // look at in_data how was defined.
your code will look like:
#include<iostream>
#include <string>
using namespace std;
class ques
{
public: // make in_data public to use from outside
void in_data(char qu[500], char p[25], char q[25], char r[25], char s[25], char ans1) // so pass eg: 'a' not "a"
{
strcpy(question, qu);
strcpy(a, p);
strcpy(b, q);
strcpy(c, r);
strcpy(d, s);
ans = ans1;
}
private:
char question[500];
char a[25];
char b[25];
char c[25];
char d[25];
char ans;
};
int main()
{
ques q[2];
q[0].in_data("what is 2+2","alpha","beta","gamma","delta",'d');
q[1].in_data("choose a","a","b","c","d",'a');
return 0;
}
Finally why don't you use class string as long as it is a must in your code instead of using arrays of characters?

Vector of structs with using structs out of other class

I need to create and use vector with structs of other class.
So class Scanner contains following struct structure:
class Scanner
{
struct structOneScan
{
unsigned int X_MULTIPLE_POS[290];
unsigned int Z_MULTIPLE_POS[290];
unsigned int I_MULTIPLE_COUNT[290];
}
structOneScan SnapsArray[3000] ;
};
in Draw.cpp i manipulate this struct:
if (Counter<3000)
{
for(int i = 0; i < 290; i++)
{
Scanner.SnapsArray[Counter].X_MULTIPLE_POS[i] = (double) (Scanner.X_POS[i] * X_Factor);
Counter ++;
};
Now that i have the information copied in my SnapsArray, i need to analyse this information and save it in a vector, cause there can be many such Scans.
Thats why i create another class CMeasurementResult, to save the structs in a vector:
#include "CScanner.h"
#include <vector>
using namespace std;
class CMeasureResult
{
public:
vector<structOneScan*>Scans;
};
but the way i try it doesn´t work. Also tried it over a Pointer from Scanner, but it doesn´t work too.
vectorScans; doesn´t work too.
vectorScans; ist the declaration. Qualifier 'scanner' is not a name of a class or namespace. Tempaltespecification out of 'vector<_Ty,_Ax>' can´t be generated. Sorry for bad translation, my compiler is in German language. So if I compile, this ist the Error. C++ Builder Embarcadero

How to return an array of structs from a class in a getter function

I have a relatively simple question but I cant seem to find an answer specific for my case and I just may not be approaching this problem the right way. I have a class that looks like this:
struct tileProperties
{
int x;
int y;
};
class LoadMap
{
private:
ALLEGRO_BITMAP *mapToLoad[10][10];
tileProperties *individualMapTile[100];
public:
//Get the struct of tile properties
tileProperties *getMapTiles();
};
I have an implementation that looks like this for the getter function:
tileProperties *LoadMap::getMapTiles()
{
return individualMapTile[0];
}
I have code in the LoadMap class that will assign 100 tile properties for each struct in the array. I want to be able to access this array of structs in my main.cpp file but I just cant seem to find the right syntax or approach. My main.cpp looks like this.
struct TestStruct
{
int x;
int y;
};
int main()
{
LoadMap _loadMap;
TestStruct *_testStruct[100];
//This assignment will not work, is there
//a better way?
_testStruct = _loadMap.getMapTiles();
return 0;
}
I realize that there are many approaches to this, but I'm trying to keep this implementation as private as possible. If someone could please point me in the right direction I would greatly appreciate it. Thank you!
TestStruct *_testStruct;
_testStruct = _loadMap.getMapTiles();
This will get you a pointer to the first element in the array returned. You can then iterate through the other 99.
I would highly recommend using vectors, or another container, and writing getters that don't return pointers to bare arrays like that.
First of all, here, why do we need TestStruct, you can use "tileProperties" structure itself...
And imp thing,
tileProperties *individualMapTile[100]; is array of pointers to the structure.
Hence, individualMapTile will have pointers in it.
You have returned the first pointer, hence you can access the first structure only. What about the others????
tileProperties** LoadMap::getMapTiles()
{
return individualMapTile;
}
int main()
{
LoadMap _loadMap;
tileProperties **_tileProperties;
_tileProperties = _loadMap.getMapTiles();
for (int i=0; i<100;i++)
{
printf("\n%d", (**_tileProperties).x);
_tileProperties;
}
return 0;
}
Use vectors instead of arrays where possible. Also consider an array/vector of TestStruct directly rather than pointers to them. I can't tell if that would be appropriate for you from your code sample.
class LoadMap
{
public:
typedef vector<tileProperties *> MapTileContainer;
LoadMap()
: individualMapTile(100) // size 100
{
// populate vector..
}
//Get the struct of tile properties
const MapTileContainer& getMapTiles() const
{
return individualMapTile;
}
MapTileContainer& getMapTiles()
{
return individualMapTile;
}
private:
MapTileContainer individualMapTile;
};
int main()
{
LoadMap _loadMap;
LoadMap::MapTileContainer& _testStruct = _loadMap.getMapTiles();
}