I have ran into a problem yesterday when trying to split my code into several files.
Yesterday morning my whole code was in one file and to keep track of everything more easily I wanted to split the code into more files.
This went well until I got to a function where I need to declare a variable although I already have (but maybe in the wrong place).
Because the code is too long, I have put all files to pastebin.
I have declared "field" in main.cpp:
char field[20][41];
Whole file here: https://pastebin.com/Jy1XvdpL
And I want to use this in my field.cpp:
void loadLevel(int levelnumber) {
// concatenate leven base with level number
std::string level = "level" + std::to_string(levelnumber) + ".txt";
// print field
// load the text file
std::ifstream file;
file.open(level);
char c;
// read line by line, character by character and store it in field
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 41; j++) {
file.get(c);
field[i][j] = c;
}
}
file.close();
}
The field.h looks like this:
#ifndef field
#define field
#include <iostream>
#include <string>
#include <fstream>
void loadLevel(int levelnumber);
void drawField();
#endif // !field
The problem is that I do not know, where to define char field because I get an error if done in either of these files. So what do I need to do to get char field workin in field.cpp and therefore work in my main?
P.S. This is my first program in c++ and I am learning new things everyday. I appreciate any hints on how to do certain things better ^^
Kind Regards,
Benjamin
When you declare a variable in your main file, you are not able to use it in another file. (or at least easily)
if you wish to use your field variable in the field.cpp, then you can define it in field.h.
Code for this could be as followed.
#ifndef field
#define field
#include <iostream>
#include <string>
#include <fstream>
void loadLevel(int levelnumber);
void drawField();
char field[20][41];
#endif // !field
Though this will not allow you to use the information you assign to field[i][j] will not be available in your main file.
To do this I would make a function in field.h and field.cpp that returns the value of field[i][j].
You can use field array in your function by passing it as an argument to your loadlevel function, check this question too if you want to use pointers.
So your function will look like:
void loadLevel(int levelnumber,char field[][41]);
Related
Related to this. I'd like to avoid using global variables so I resorted to using structs with enum and std::string[] (see link) in order to build menus for a small application. I would also like to have these enums in a separate header file. The selected answer in the link implies using --std=c++17, which I'd like to avoid, at least for now, and decided to use a static const std::string[] -- no need to include extra array or vector since this is initialized once, never modified, only called, ALL is always known.
As other answers on this have made it clear, I need to either initialize A::names outside the struct, or use a static const std::string& setter (see this, for example). But all the answers so far dealt with a std::string, not an array, std::string[].
This is a simple example of what I tried. It simply tries to print the contents of A::names using a for() loop iterating through the enum in struct A:
a.h:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
#include <string>
struct A
{
enum E { ONE, TWO, ALL };
static const std::string names[ALL];
};
#endif // A_H_INCLUDED
a.cpp:
#include "a.h"
static const std::string A::names[A::ALL] { "one", "two" };
main.cpp:
#include "a.h"
#include <iostream>
int main()
{
for(int i=A::ONE; i<A::ALL; ++i)
std::cout << A::names[i] << '\n';
return 0;
}
The error after g++ main.cpp is:
main.cpp:(.text+0x24): undefined reference to `A::names[abi:cxx11]'
collect2: error: ld returned 1 exit status
Seeing the cxx11, I thought g++ --std=c++11 main.cpp would solve it, but it doesn't.
So, what am I doing wrong, or, how could I adapt the version with the setter to return an array, std::string[]? My goal is to have an alternative to a global variable, that has only one instance in memory no matter how many calls.
Here's an adapted code, from a small program, on how I would build a menu using struct with enum and string (menu_design = new QMenu... and menuDesignAction() is the function that updates):
for(unsigned char i=0; i<A::ALL; ++i) // needs initializing
{
QAction *tmpAction {new QAction(tr(A::names[i].c_str()))};
tmpAction->setObjectName(QString("%1").arg(i));
connect(tmpAction, SIGNAL(triggered(bool)), this, SLOT(menuDesignAction()));
menu_design->addAction(tmpAction);
}
As a side-note, in the snippet above, I have to use .c_str(), but I am using a std::string in the enum. If I could make it *char[] instead of std::string[], would I avoid extra calls? If I am not wrong, how could the answers to my problem (assuming there are) be adapted so as to be able to fit somehow in the Qt snippet?
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
Ok so I'm still getting used to C++ again, so this error may seem simple. I'm attempting to create a simple class with a three member functions (I'm only trying to call one of them in this). So I create the class, instantiate an object, then attempt to call the function using that object and this error comes up:
Code.cpp:(.text+0x15): undefined reference to `Code::genCode()'
I've double checked to see if it was an error with the function itself, but that is not the case. I've seen others post about this issue but there seems to be a multitude of situations and solutions. Anyway here's the code:
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <list>
using namespace std;
class Code {
public:
int genCode();
int checkCorrect();
int checkIncorrect();
};
int main()
{
Code c1;
c1.genCode();
}
////////////////FUNCTIONS/////////////////////////
int genCode()
{
vector <int> newcode;
srand(time(NULL));
for(int i = 0; i < 9; i++){
int x;
x = (rand() % 6);
if (find(newcode.begin(),newcode.end(), x) == newcode.end())
{
newcode.push_back(x);
}
}
if (newcode.size() > 4)
{
newcode.pop_back();
}
for(int i = 0; i < 4; i++)
{
return newcode[i];
}
}
int checkCorrect()
{
}
int checkIncorrect()
{
}
you need to put class name before method name
the format is
'returnType Classname::methodname
{
codes
}'
int code::genCode()
{
//codes
}
or you also possible to write code in class
Change the implementation of the methods of your class to the following:
int Code::genCode()
{
...
}
int Code::checkCorrect()
{
...
}
int Code::checkIncorrect()
{
...
}
You are defining the functions outside the class. Put them inside the class, then you don't need to declare them inside the class. Directly define them.
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <list>
using namespace std;
class Code {
public:
////////////////FUNCTIONS/////////////////////////
int genCode()
{
cout << "Inside genCode. Just for Debugging purpose." << endl;
vector <int> newcode;
srand(time(NULL));
for(int i = 0; i < 9; i++){
int x;
x = (rand() % 6);
if (find(newcode.begin(),newcode.end(), x) == newcode.end())
{
newcode.push_back(x);
}
}
if (newcode.size() > 4)
{
newcode.pop_back();
}
for(int i = 0; i < 4; i++)
{
return newcode[i];
}
}
int checkCorrect()
{
}
int checkIncorrect()
{
}
};
int main()
{
Code c1;
c1.genCode();
}
Otput:
Inside genCode. Just for Debugging purpose.
The function
int genCode()
Is what's called a free function. It is not bound to a class.
In order for the compiler to know that genCode is part of a class, you have to tell it by explicitly stating the namespace to which genCode belongs.
int Code::genCode()
However since it appears code Code is entirely contained within one file, following CodeRunner's advice will lead to a cleaner implementation.
But why would anyone want to got the trouble of splitting everything up?
Separating the class definition from the method implementations allows you place the class definition into one file, the 'h header file, and the methods in an implementation file, usually a .cpp file. The header file is then shared with users of the Code object and the implementation file can be compiled into a library and hidden from the callers view.
There are a number of reasons to do this, but most of them have to do with creating pre-compiled libraries and using them to reduce build times.
With a library, you build the library once, and then compile the rest of the code that uses the library over and over until you get it right. Can you imagine how long it would take to build a program if you had to rebuild the C++ standard library every time you fixed a bug and wanted to test?
Had a job like that once. Had to spend four hours compiling third party network code every time I made a fix because the company's paranoid build system rebuilt everything every time. Off by one error? 4 hours. Need to add a debug line? 4 hours. You could make and test three changes a day. Sure, you can batch up a bunch of fixes, but if one failed spectacularly and broke the system, which one was it? Sooner or later you're reduced to a crawl, making tweaks, building, testing, profiling one at a time. Fortunately I was working on contract and paid by the hour.
Another good example is you can have one library that supports Windows and other libraries supporting QNX and other operating systems. All use the same header and the user can write a program that, in theory, will operate on all supported platforms simply by recompiling the user's code. It's never quite that clean, but one can dream.
The library can even be replaced with an updated library without requiring changes or compilation of the user's code and different variants of the library can exist for different needs. A debug version with extra logging, for example.
Perhaps the implementation is not intended for public eyes. The users get to see the header and call functions in the library, but no more.
This is a silly question with something that must be an easy answer, but after hours of searching I cannot find the answer. What I need to do is have a pair of .cpp files, say main.cpp and help.cpp that have a variable, vars1 that they share and can both change the value and detect when that value has been changed. The way that would make sense to me is that I would simply declare the variable in a class inside a header file and include that header file in both .cpp files, but that doesn't seem to work.
Here is a copy of my code:
#include <iostream>
#include <fstream>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "variables1.h"
using namespace std;
int main(){
variables1 vars1;
do {
cout << "Welcome\n If you need help, type 'yes' now\n";
cin.getline(vars1.input, 1024);
if (strcmp(vars1.input, "yes") == 0 || strcmp(vars1.input, "Yes") == 0){
vars1.helpvar = true;
cin.get();
}
else{
cout << "Okay then, glad that you know your way around\n";
}
cin.clear();
cout << "What would you like to do?\n";
cin.getline(vars1.input, 1024);
if (strcmp(vars1.input, "logon" ) == 0 ) {
}
} while (0 == 0);
}
help.cpp:
#include <iostream>
#include "variables1.h"
using namespace std;
int help(){
variables1 vars1;
do {
if (vars1.helpvar == true)
cout << "detecting";
} while (0 == 0);
}
variables1.h:
class variables1
{
public:
bool helpvar;
char input[1024];
};
Actually what you are doing is that for the main file and the help.cpp you are creating two different objects and are setting the helpvar variable for each of them separately. What you want is to have a single object that is used by both help.cpp and main to only modify a single instance of the helpvar variable.
Change your help function to be along the lines of
int help(const variables1& myHelpobject ){
if (myHelpobject.helpvar == true) {
cout << "detecting";
}
}
and then call the function in main as:
help(vars1)
What you were doing before was creating a separate, independent, help object.
Here we are creating the object in main and then passing a reference to it to the function.
The technique to use depends on the purpose of your variable.
If it is some sort of global parameters, that you have to use throughout all your code, the simplest is to define it as a global variable:
main file:
variables1 vars1; // outside all functions
int main(){
...
}
Either in variables1.h or in the other cpp files using the variable:
extern variables1 vars1; //outside all functions
However the code to initialise and maintain these variables in a should also be defined in the class. The constructor shall for example define the values by default, such as if help is enable or disabled.
If your variables are for communicating between different parts of your code, and especially if the main goal of some code is to process the content of these variables, then should better make this clear by passing the variable as parameter (by reference (&) if the communication is bidirectional, or by value).
There are 2 main issues with the code as posted:
int help() is never run
Something needs to call this function for it to run. There isn't anything doing that so regardless of the value of vars1.helpvar you are never going to see "detecting" output.
Consider adding a help.hpp with the definition of the function and call the function from main.
vars1.helpvar is not shared between main and int help()
Currently you have two instances of variables1 and helpvar is a member variable so each instance has a separate copy.
You could either:
Make helpvar a static member of variables1
Share once instance of variables1 between both main and help.
The use of static variables is more likely give design problem later so I'd favour option 2.
I have been working on a header file for the past couple hours and am having an issue outputting a value that is stored in the constructor. The value is an int but it won't let me store any number above 7 and when I output it using a function it comes out a totally different number. I am doing this all within a header file and using a function in the .cpp to output the data. I'm fairly new to C++ so it's probably an amateur mistake. Any help would be appreciated!!
Header File ----
#ifndef PATIENT_DEMO_CLASS
#define PATIENT_DEMO_CLASS
// system defined preprocessor statement for cin/cout operations
#include <iostream.h>
// programmer defined preprocessor statement for setreal operation
#include "textlib.h"
// programmer defined preprocessor statement for String
#include "tstring.h"
class PatientDemographicInformation
{
private:
int patientDateOfBirth;
public:
// constructor
PatientDemographicInformation(int dateOfBirth);
// returns the patient's age
int getPatientAge( );
};
PatientDemographicInformation::PatientDemographicInformation(int dateOfBirth)
{
patientDateOfBirth = dateOfBirth;
}
int PatientDemographicInformation::getPatientAge( )
{
return patientDateOfBirth;
}
#endif
.cpp ----
#include <iostream.h>
#include <tstring.h>
#include "PatientDemographicInformation.h"
int main( )
{
PatientDemographicInformation john(11161990);
cout << john.getPatientAge() << endl;
return 0;
}
Pure guess, here.
In C, C++ and many other languages, integers written with a leading 0 are octal; that is, they are in base 8 rather than base 10.
If you're doing something like:
dateOfBirth = 070503;
then that will be interpreted as an octal number (28995 in decimal). Since octal numbers can only have digits 0-7, the following will be illegal:
dateOfBirth = 090503;
I suggest you don't encode dates in this form, if that's what you are doing.
I was working on a project and started a new class. I wanted to use a vector to store pointers of functions and then call them. Getting the function pointer and calling it was not a problem, however storing them was. I tried storing them in a vector, but it keeps emptying itself. I've tried making the vector a member of a class and an extern, both don't work. I've never had this problem ever before, and I have no clue why this is happening. Here is my current code:
TickHandler.h:
#include <iostream>
#include <ctime>
#include <vector>
class tickHandler {
public:
void addTickingFunction(void(*func)());
void onTick(void);
std::vector<void(*)()>funcs;
};
extern tickHandler TickHandler;
TickHandler.cpp:
#include "TickHandler.h"
tickHandler TickHandler;
void tickHandler::addTickingFunction(void(*func)())
{
funcs.push_back(func);
std::cout << funcs.size() << std::endl;
}
void tickHandler::onTick()
{
std::cout << funcs.size() << std::endl;
for (int i = 0; i< funcs.size();i++)
{
funcs[i]();
}
}
The expected output would be:
1
1
but instead it is:
1
0
Any help would be greatly appreciated.
EDIT: There is a lot of code in the project, but the class is only being accessed by 2 functions:
TickHandler.addTickingFunction(&physicsTick);
and
TickHandler.onTick();
Firstly, I'd suggest you put some guards around that header file, e.g.:
#ifndef TICKHANDLER_H
#define TICKHANDLER_H
// Class declaration.
#endif
I am taking a shot in the dark here, but I think your problem is that you are adding your physics tick functions to one instance of a tick handler, but running them in another. I don't think they are disappearing.
You've somehow got two instances of the TickHandler class lying about. Given this is C++ and it is an object-orientated language, the extern TickHandler and the global instance created in your .cpp file is setting off alarm bells for me.