I was doing a project for computer course on programming concepts. This project was to be completed in C++ using Object Oriented designs we learned throughout the course. Anyhow, I have two files symboltable.h and symboltable.cpp. I want to use a map as the data structure so I define it in the private section of the header file. I #include <map> in the cpp file before I #include "symboltable.h".
I get several errors from the compiler (MS VS 2008 Pro) when I go to debug/run the program the first of which is:
Error 1 error C2146: syntax error : missing ';' before identifier 'table' c:\users\jsmith\documents\visual studio 2008\projects\project2\project2\symboltable.h 22 Project2
To fix this I had to #include <map> in the header file, which to me seems strange.
Here are the relevant code files:
// symboltable.h
#include <map>
class SymbolTable {
public:
SymbolTable() {}
void insert(string variable, double value);
double lookUp(string variable);
void init(); // Added as part of the spec given in the conference area.
private:
map<string, double> table; // Our container for variables and their values.
};
and
// symboltable.cpp
#include <map>
#include <string>
#include <iostream>
using namespace std;
#include "symboltable.h"
void SymbolTable::insert(string variable, double value) {
table[variable] = value; // Creates a new map entry, if variable name already exist it overwrites last value.
}
double SymbolTable::lookUp(string variable) {
if(table.find(variable) == table.end()) // Search for the variable, find() returns a position, if thats the end then we didnt find it.
throw exception("Error: Uninitialized variable");
else
return table[variable];
}
void SymbolTable::init() {
table.clear(); // Clears the map, removes all elements.
}
My guess is that you have another file that includes the header file #include "symboltable.h". And that other source file doesn't #include <map> nor #include <string> nor has using namespace std before it includes "symboltable.h".
Check which file is being compiled when you get the error. Is it maybe a different source file than the .cpp that you mentioned? Possibly something like main.cpp?
Another way to solve your problem is to put the includes you need in your header file and use std::map instead of simply map. Also you use string which is also inside the namespace std. So that needs to be std::string. And put the missing #include <string>.
Yes, you indeed have to #include <map> in the header file.
You use map in the declaration of the class, so the compiler needs to know what this map refers to. Since the definition of it is in <map> you need to include that header before using the map template class.
You could also instead #include <map> in every source file before the #include "symboltable.h" line, but usually you would just include these kind of prerequisites in the header.
Related
So I was trying to access a method that is defined in another class and has the prototype in the header. I'm pretty positive I defined it but it keeps popping up undefined reference to SafeCracker.
Main.cpp
#include <iostream>
#include "mystuff.h"
using namespace std;
void BigDog(int KibblesCount);
int main()
{
cout << SafeCracker(1);
return 0;
}
mystuff.cpp
#include <iostream>
using namespace std;
string SafeCracker(int SafeID)
{
return "123456";
}
mystuff.h
using namespace std;
#ifndef MYSTUFF_H_INCLUDED
#define MYSTUFF_H_INCLUDED
string SafeCracker(int SafeID);
#endif // MYSTUFF_H_INCLUDED
Here it tells you that you have an undefined reference, so you don't really have a problem with the prototype.
Had you forgotten to include the header file that contains the prototype you would have gotten something like
main.cpp: In function ‘int main()’:
main.cpp:8:13: error: ‘SafeCracker’ was not declared in this scope
cout << SafeCracker(1);
Your undefined reference is a linker error. The most likely cause would be that you did not use mystuff.cpp when compiling
If you're compiling from the command line, you should give both files as parameters.
If you're using an IDE that calls the compiler, make sure that the file is part of the project.
For example in Code::Blocks right-click on the file name and go "add to project" (If I remember correctly)
It is also possible that you made a typo in the function declaration in mystuff.cpp (that doesn't seem to be the case here though)
Now there is one important thing about your code you should take note of:
It is very bad practice to put a using namespace in a header file.
using namespace std; in a .cpp source file is mostly up to you, and that using statement will only apply to that particular file.
But if you put it in a header file that is meant to be included through #include , the using there will be forced upon any code that includes it.
Here is an example:
main.cpp
#include <iostream>
// including mystuff.h to use that awesome SafeCracker()
#include "mystuff.h"
// I need to use an std::map (basically an associative array)
#include <map>
// the map of my game
class map
{
int tiles[10][10];
};
int main()
{
// The std map I need to use
std::map<int, int> mymappedcontainer;
// The map of my game I need to use
map mytiles;
// The reason why I need to include mystuff.h
cout << SafeCracker(1);
return 0;
}
Normally, my class map should not be a problem since the map I included from the standard library is inside the namespace std, so to use it you would need to go std::map.
The problem here is that, since mystuff.h has using namespace std; in it, the symbol map is already used, and that creates a conflict.
You do not now who will use your header files, or if you will use them again a long time from now, and maybe then you will want to use name that is already used in the std namespace.
I advise you to use std:: before things taken from the standard libraries instead (std::string instead of just string for example)
PS: In C++, "class" refers to a class data structure, and the functions you made here are not part of any class. You should say "defined in another file" or "defined in another translation unit" instead
I was splitting up my program into a header and implementation file per usual, however, when I tried to run the code, I got a ton of compile errors. This seems to be an issue with my computer or IDE, but I have not seen it before. This should be relatively simple as it is for a class project.
The code is as follows:
colorPicker.h
#pragma once
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
colorPicker.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
colorPicker::colorPicker() {
colorArray[0] = "Red";
colorArray[1] = "Green";
colorArray[2] = "Purple";
colorArray[3] = "Yellow";
colorArray[4] = "Orange";
colorArray[5] = "Indigo";
colorArray[6] = "Pink";
}
void colorPicker::printAllColors() {
for (int i = 0; i < 7; i++) {
cout << colorArray[i] << endl;
}
}
string colorPicker::randomColor() {
srand((unsigned)time(0));
int j = 0;
j = rand() % 7;
return colorArray[j];
}
main.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
colorPicker p;
p.printAllColors();
cout << "Random Color: " << p.randomColor() << endl;
system("pause");
return 0;
}
There are 20 errors given by the compiler, however, they all seem to be stemming from two undeclared identifiers which are most definitely declared. I am at a loss for what I could possibly do to fix it, and this project is due Sunday. Thank you.
Here are the errors
Tons of Errors
You need #include "colorPicker.h" in colorPicker.cpp. Each .cpp file is handled basically independently by the compiler and they are all joined at the end by the "linker." When the compiler looks at colorPicker.cpp without an include of the corresponding header, it's at a loss as to the definition of all the classes you're working with.
There are a few things you are doing wrong. I'll just pick on a couple.
Firstly, each header file you write should be self-contained - in the sense that, if it relies on content of some other headers, it includes that header. If a compilation unit (a formal name for a source file with a .cpp in your case) includes your header, it should not have to include something else your header depends on.
Second, it is a bad idea for a header to rely on any using directive, such as using namespace std. There are plenty of explanations of that available, so I won't repeat.
To understand the above, look at colorPicker.h
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
Firstly, this depends on string, but there is no definition of string visible in the header file. Usage of that type depends on the standard header <string>.
Second, that string type is within namespace std. So your header relies on the compilation unit (the source file that includes your header) having previously used a using directive i.e. using namespace std.
To fix these two problems, change the header to
#ifndef SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#define SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#include <string>
class colorPicker
{
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
(I've also done some minor changes of layout, since I have various reasons to prefer that.
However, the #include <string> means that this version will not fail to compile, as yours does, if it is included by a compilation unit that does not have #include <string>.
The usage of the fully qualified name std::string, rather than string, also means there is no dependence on the using directive using namespace std. It also means compilation errors can't be triggered in your header if your compilation unit has another using directive.
I've also used an include guard, rather than #pragma once. Although most modern compilers support #pragma once, it is actually not standard C++ (a #pragma, by definition in the standard, is a compiler-specific hook). Include guards are supported in standard C++.
If you've done that, your code should mostly compile as is. However, optionally, you may wish to
remove the using directives using namespace std from your other files. If you do that, you will need to change the definition of colorPicker::randomColor() in colorPicker.cpp so it returns the fully qualified type std::string rather than string.
Remove #include <string> from files that have #include "colorPicker.h". This is possible, since colorPicker.h now includes <string>. This step is optional, since there is no problem with including standard headers more than once in a compilation unit.
A few other notes
In C++, although it is not a major concern, it is usually considered better to use include <cstdio> and <cstdlib> rather than the C headers <stdio.h> and <stdlib.h>.
Your code is calling srand((unsigned)time(0)) whenever colorPicker::randomColor() is called. It is better to only call it once in an entire program, not in a function that may be called multiple times.
A header file should be self-contained as far as #includes go. That means that you should be able to #include the header file without having to include other stuff before it!
Your colorPicker.h does not meet that requirement. It apparently uses std::string from the standard library but does not have an #include <string> on top, so everyone who uses colorPicker.h has to remember to put an #include <string> before it. That's pretty annoying.
Even worse, colorPicker.h refers to std::string as string, which implies a using std::string; or using namespace std; somewhere before any #include "colorPicker.h" line, and both of those are very bad coding style in C++, if not used in tighter scopes.
Here's how to fix the header file:
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
As far as your *.cpp files go, I can see that you are using #include "stdafx.h". Why? It's a non-standard Microsoft thing completely unnecessary in your case. You are also using it incorrectly. It must be the first include. Just remove it entirely.
Some other suggested cleanup:
using namespace std; lines in *.cpp files is not as bad as in header files, but if I were you, I'd just get rid of it completely. Just use complete names. Say std::cout, not cout. And so on. It's just the most consistent way and it avoids a lot of trouble.
You include a lot of headers which you don't need. For example, what's <ctime> for?
Don't use system("pause");. Do not look for artificial ways of pausing a command-line program.
You may need add head file and in colorPicker.h.
And the std namespace is needed while using string.
BTW, the header guards is recommended strongly.
#ifndef COLOR_PICKER_H
#define COLOR_PICKER_H
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
I have a multifile program, and I can't figure out why my program says that "Customers" (in the registerNewUser() function) is an undeclared identifier.
proc.h
#ifndef PROC_H
#define PROC_H
#include <iostream>
#include "const.h"
#include "customers.h"
#include <fstream>
using namespace std;
void registerNewUser(Customers cBase); // Add new user.
#endif // !PROC_H
I have included the header file (customers.h) with the Customers class also.
customers.h
#ifndef CUSTOMERS_H
#define CUSTOMERS_H
#include <iostream>
#include "const.h"
#include "proc.h"
#include "customer.h"
using namespace std;
class Customers {
private:
char* current;
List* customerList; // List for customers.
public:
Customers(); // Constructor.
~Customers(); // Destructor.
void handler(); // Customers handler/menu.
void addNew(char username[]);
};
#endif // !CUSTOMERS_H
Can anyone see what's wrong?
You have a circular include. customers.h includes proc.h so basiacally
void registerNewUser(Customers cBase);
Will get added to customers.h before the compiler has seen what a Customer is. It looks like you should just be able to remove the #include "proc.h" in customers.h and it should compile.
As stated in the comments above you should never use using namespace std; in a header file as anything that includes it now has the entire std namespace exposed. You should also get in the habit of only using it in the most narrow scope you can or drop it completely. For further reading on the use of using namespace std; see Why is “using namespace std” in C++ considered bad practice?
Basically including "customers.h" in "customers.h" wouldn't be a problem here, since you have a guard (plus point for that). Nevertheless it is not very nice.
As NathanOliver said it COULD be a problem with the order of the includes but it doesn't have to. If you include proc.h first everything is fine. If you include customers first, the compiler includes proc.h before he sees the customer class. proc then wont include customers.h (since its guard prevents it). Then he will find your function not knowing what "Customer" means. So depending on the include order of your header files it will or will not work.
If you want a hint: I normally first only include the necessary files for a forward declaration, then do a forward declaration. Then I include the files necessary files for the definition of the class (These will already know that the class exists). The complete class declaration (with member function declaration) follows. If you do it like this you can avoid many mistakes. In your case:
#ifndef CUSTOMERS_H
#define CUSTOMERS_H
class Customers;
#include "proc.h"
#include "ListTool2B.H"
using namespace std;
class Customers
{
private:
char* current;
List* customerList; // List for customers.
public:
Customers(); // Constructor.
~Customers(); // Destructor.
void handler(); // Customers handler/menu.
void addNew(char username[]);
};
#endif
This is probably a duplicate: you have proc.h including customers.h and customers.h including proc.h this will cause a circular reference, and looks like proc.h included in customers is not necessary, so you could try simply to delete this line:
#include "proc.h"
After fixing the previous problem (see my one other question that I have asked). I had declared more classes.
One of these is called CombatAdmin which does various things: (Header file)
#ifndef COMBATADMIN_H
#define COMBATADMIN_H
#include <string> // Need this line or it complains
#include <Player.h>
#include <Sound.h>
#include <Enemy.h>
#include <Narrator.h>
using namespace std;
class Enemy;
class Player;
class CombatAdmin // Code yet to be commented here, will come soon.
{
public:
CombatAdmin();
void healthSet(double newHealth, string playerName);
void comAdSay(string sayWhat);
void playerFindsChest(Player *player,Weapon *weapon,Armour *armour);
void youStoleOurStuffEncounter(Player *player);
void comAdWarning(string enemyName);
void comAdAtkNote(string attack, double damage,string target,string aggresor);
void entDefeated(string entName);
void comAdStateEntHp(string ent, double hp);
void comAdStateScanResults(string enemyName, double enemyHealth);
string doubleToString(double number);
string intToString(int number);
bool isRandEncounter();
void randomEncounter(Player *player,Sound *sound,Narrator *narrator);
bool combatRound(Player *player, Enemy *enemy, Sound *sound, bool ran);
void playerFindsItem(string playerName,string itemName,double itemWeight,double playerWeight);
void playerFindsGold(string playerName,double coinCnt,double playerCoinCnt);
};
#endif // COMBATADMIN_H
It is then instanced in the main.cpp file like this: (Snippet of the main.cpp file)
#include <iostream> // Required for input and output
#include <Item.h> // Item header file.
#include <Weapon.h> // Header files that I have made for my classes are needed for this program
#include <sstream> // Needed for proper type conversion functions
#include <windows.h> // for PlaySound() and other functions like sleep.
#include <time.h> // Needed to seed the rand() function.
#include <mmsystem.h> // Not sure about this one, possibly defunct in this program.
#include <stdio.h> // Needed for a similar kind of output as iostream for various functions error msgs.
#include <irrKlang.h> // The header file of the sound lib I am using in this program.
#include <Narrator.h> // The narrators's header file.
#include <Pibot.h> // Other header files of classes.
#include <Armour.h>
#include <Player.h>
#include <Weapon.h>
#include <CombatAdmin.h>
using namespace irrklang;
using namespace std;
// Forward referenced functions
void seedRandom(); // Seeds the random number so it will be random as apposed to pseudo random.
string getPlayerName(string temp); // Gets the player's new name.
int main(int argc, char* argv[])
{
// Variables and object pointers declared here.
CombatAdmin *comAd = new CombatAdmin(); // Handles combat.
Narrator *narrator = new Narrator(); // The Narrator that says stuff
Pibot *piebot = new Pibot(); // PIbot, the player's trusty companion
string temp; // Temp string for input and output
However, when I try to compile the project, I get the following error:
C:\Documents and Settings\James Moran.HOME-B288D626D8\My Documents\C++ projects\Test Project\main.cpp|59|undefined reference to `CombatAdmin::CombatAdmin()'|
I am using the Code::Blocks IDE (ver 10.05), with the GNU GCC compiler. The project is of type "Console application". I am using windows XP 32 bit SP3.
I have tried changing to search directories to include where the object files are, but no success there.
As can be seen from the code, the narrator and PIbot are instanced just fine. (then used, not shown)
My question is, therefore, what do I need to do to stop these errors occurring? As when I encountered similar "Undefined reference to x" errors before using libraries. I had just forgotten to link to them in Code::Blocks and as soon as I did, they would work.
As this class is of my own making I am not quite sure about this.
Do say if you need more information regarding the code etc.
You have declared the default constructor (CombatAdmin()) and thus prevented the compiler from automatically generating it. Thus, you either need to 1) remove declaration of the default constructor from the class, or 2) provide an implementation.
I had this kind of error and the cause was that the CombatAdmin.cpp file wasn't selected as a Build target file: Prject->Properties->Build targets
Are you sure you've to include your header as:
#include <CombatAdmin.h>
?
I think you need to include your header file as:
#include "CombatAdmin.h"
And same for other headers written by you, like these:
#include "Armour.h"
#include "Player.h"
#include "Weapon.h"
//and similarly other header files written by you!
See this topic:
What is the difference between #include <filename> and #include "filename"?
My solution was just to add a line in the header before the class defenition:
class CombatAdmin;
Hey guys, I just started learning C++ and I have this code that I have to complete but the class header is giving me this error
error: string: No such file or directory
#include <vector>
#include <string>
class Inventory
{
public:
Inventory ();
void Update (string item, int amount);
void ListByName ();
void ListByQuantity ();
private:
vector<string> items;
};
your code should probably look something more like this:
#include <string>
#include <vector>
class Inventory {
public:
Inventory();
void Update(const std::string& item, int amount);
void ListByName();
void ListByQuantity();
private:
std::vector<std::string> items;
};
if #include <string> is in fact your include directive, then you may be compiling the file as a c program. the compiler often determines language by the file extension. what is your file named?
I don't think your error is anything to do with namespaces.
You say you're getting error: string: No such file or directory which implies that the pre-compiler cannot find the STL string definition file. This is quite unlikely if you're also including vector and having no problems with that.
You should check your compilation output for clues about where it's picking header files from. Any chance you could post the full compilation output?
Either use using std::string (not recommended) or replace string with std::string.
Or, if I have misunderstood, use #include <string> instead of #include "string".
Same goes for vector which is also in std namespace.