C++ Program cannot compile properly using CMD howerever complies within VSC - c++

A program im writing successfully runs on the IDE visual studio code. However, when attempting to use the Bitvise SSH client to run my program I get a list of errors that I myself cannot understand the problem for. Bitvise it another way to access the CMD client from a remote server, for all intenstive purposes it acts the same as windows CMD. I will provide a screen cap of the errors and a full run down of the parts of my program that I believe are causing the errors. If any further code is required please feel free to ask.
errors screen cap
This error report shows a common error, with something being a placeholder for all instances.
multiple definition of `something' /tmp/ccBhjFYn.o:(.bss+0x0): first defined here
This error DOES NOT happen in visual studio code
From this error report it can be seen the issue is found within driver.cpp and my header.h file. For this reason i wont provide a minimal code for these files, but they are small enough to not require one.
MAIN
int main()
{
Customer c;
Part p;
Builder b;
const string fileName = "Parts.txt";
auto partsVec = readpartFile();
auto customerVec = readcustomerFile();
auto builderVec = readbuilderFile();
fexists(fileName);
complexity(c, partsVec);
robotComplexity(partsVec,customerVec);
writeFile(buildAttempt(b, complexity(c, partsVec), variability(customerVec, builderVec)));
return 0;
}
HEADER FILE
#include <vector>
#include <string>
struct Customer {
std::string customerName;
std::string projectName;
std::string listofParts;
} myCustomer;
struct Part {
char partCode;
std::string partName;
int maximum;
int minimum;
int complexity;
} myPart;
struct Builder {
std::string builderName;
int ability;
int variability;
} myBuilder;
bool fexists(const std::string filename);
std::vector<Part> readpartFile();
std::vector<Customer> readcustomerFile();
std::vector<Builder> readbuilderFile();
float complexity(const Customer& c, const std::vector<Part>& parts);
void robotComplexity(const std::vector<Part>& vecB, const std::vector<Customer>& vecC);
double variability(const std::vector<Customer>& customerList, const std::vector<Builder>& builderList);
std::vector<double> buildAttempt(Builder b, double variaiblity, double complexityRobot);
void writeFile(std::vector<double> build);
Thankyou for any help. This question may be hard to understand and follow but i did try my best. Any sugguestions to help improve this question are welcome but please be friendly :)

This in header.h
struct Customer {
std::string customerName;
std::string projectName;
std::string listofParts;
} myCustomer;
Is a definiton of a global variable myCustomer. As such it does not belong in a header file.
Change the header file to this
struct Customer {
std::string customerName;
std::string projectName;
std::string listofParts;
};
extern Customer myCustomer; // global variable declaration
Then to one of your cpp files (I suggest implementation.cpp) add this
Customer myCustomer; // global variable definition
Or you could just do away with global variables completely (the best solution).
NOTE in some of my comments above, I said you have global variable declarations in your header file. What I meant was you have global variable definitions in your header file. The difference between a definition and a declaration is what is crucial here. It's fine to put declarations in a header file, it's wrong to put a definition. Sorry for any confusion.

Related

How to use info passed as parameter to build a string defined in other CPP file

I have a C++ program that has several .hpp files with declarations of variables (most of them paths to a NFS filesystem) and .cpp files with the definitions of those variables.
In some of those variables, whose type is std::string, I need to build its content by appending some content passed as parameter in the main program. For instance:
File constants.hpp:
namespace constants {
extern std::string cudnn_version;
extern const std::string path_caffe_cuda;
extern const std::string path_caffe_cuda_cudnn;
}
File constants.cpp:
const std::string constants::path_caffe_cuda = "/nfs/apps/caffe/cuda";
const std::string constants::path_caffe_cuda_cudnn = constants::path_caffe_cuda + "/cudnn" + constants::cudnn_version;
The content of constants::cudnn_version is asked to the user in the main program as parameter and updated there. The problem is, when constants::path_caffe_cuda_cudnn variable must be built with the content of constants::cudnn_version variable, its content is still empty, so in some way the variable path_caffe_cuda_cudnn is evaluated before the constants::cudnn_version has the content passed by user.
How do you think I could fix the issue?
Thank you very much to everybody.
It could easily be done by using a function instead:
namespace constants {
extern std::string cudnn_version;
extern const std::string path_caffe_cuda;
inline std::string path_caffe_cuda_cudnn()
{
return constants::path_caffe_cuda + "/cudnn" + constants::cudnn_version;
}
}
As long as path_caffe_cuda_cudnn is not called until constants::cudnn_version have been initialized, then it will be okay.

C++ class to read a text file - getting errors

I have the following code to read a text file using a class definition. I created the TermGrade.h file and the TermGrade.cpp file. But I get few errors:
In the TermGrade.h file I get the warning that it cannot find a definition for any of the defined functions ( Readdata, MidsemesterScore, FinalScore and LetterGrade) even though I have them defined in the .cpp file.
However, the main problem is that in the TermGrade.cpp file I get the error "Error:No instance of overloaded function "getline" matches the argument list" and it also complains that identifier "inLine" is undefined, but it does not complain about inLine in the next statement, but that statement says that both
dataLines[lineNumber] are undefined! Do I need to define these variables in the .cpp file? Any help would be greatly appreciated.
Thank you,
Bill.
// TermGrade.h file
#ifndef TERMGRADE_H
#define TERMGRADE_H
#include <string>
#include<iostream>
#include<fstream>
using namespace std;
class TermGrade {
public:
TermGrade(string fileName) {};
string StudentID;
int assignments;
int exam1;
int exam2;
int final;
bool records = true;
private:
string inLine;
string dataLines[100];
int lineNumber = 0;
bool Readdata(istream& in); // Read line of data from input file
double MidsemesterScore() const; // Calculates average
double FinalScore() const; // Calculates average
char LetterGrade() const; // Determines grade
}; // end class Termgrade
#endif
// TermGrade.cpp file
#include "TermGrade.h" // TermGrade class definition
#include<iostream>
#include<fstream>
TermGrade::TermGrade(string fileName) {
ifstream infile;
infile.open(fileName);
}
bool Readdata(istream& infile)
{
if (!infile.eof)
{
getline(infile, inLine);
dataLines[lineNumber] = inLine;
return true;
}
return false;
}
double MidsemesterScore()
{
return 0.0;
}
double FinalScore()
{
return 0.0;
}
char LetterGrade()
{
return 'a';
}
In the TermGrade.h file I get the warning that it cannot find a
definition for any of the defined functions ( Readdata,
MidsemesterScore, FinalScore and LetterGrade) even though I have them
defined in the .cpp file.
No, you don't have them defined in the .cpp file. You do not have, for example a definition of TermGrade::Readdata method. That method is not defined anywhere. You do have a function called Readdata in there, but that has nothing to do, whatsoever, with the TermGrade::Readdata method.
Regarding a few of the other errors you're getting:
You are calling a function called getline(), however you have not defined that function anywhere, and that's why you are getting that compiler error. Perhaps you meant to refer to the std::getline() function, from the C++ library, if so then that's what you should be referring to.
Also, you are passing a reference to a class called istream, unfortunately you did not define this class anywhere. If you meant to refer to the std::istream class, then you should've referenced it, as such.
However, the std::istream class does not have a member called eof. It does have an eof() method, though.

unresolved external symbol in c++ with MS visual studio 9

My code will be similar to the below code:
class DMLGroup
{
public:
DMLGroup();
~DMLGroup();
void SetName(string name);
private:
string mName;
};
void DMLGroup::SetName(string nm){
mName.assign( nm );
}
int main()
{
string api="API_DML";
DMLGroup * dmlGr = new DMLGroup();
dmlGr->SetName(api.c_str()); //Getting link error with this statement
}
I could able to compile the above code but failed to link using MS visual studio 9 on windows 7 32-bit OS.
Note: I am able to compile, link and run successfully on suselinux-x8664 platform. The problem is only with windows
Please tell me how to resolve this?
The following code compiles & links fine:
#include "stdafx.h"
#include <string>
class DMLGroup
{
public:
DMLGroup() {}
~DMLGroup(){}
void SetName(std::string name);
private:
std::string mName;
};
void DMLGroup::SetName(std::string nm){
mName.assign( nm );
}
int main()
{
std::string api="API_DML";
DMLGroup * dmlGr = new DMLGroup();
dmlGr->SetName(api.c_str()); //Getting link error with this statement
}
What I changed:
#included stdafx.h because it's VS standard - you can turn it off
#includes because it was missing
decorated every use of string with std:: - because most probably you'll use your class definition in a header file and there you simply don't use "using namespace"
supplied default implementation for constructor & destructor
That's all. Check what from the above part is missing or supply an example that exposes the problem & supply the linker error message.

(C++) Linking with namespaces causes duplicate symbol error

For the past few days, I have been trying to figure out how to link the files for a CLI gaming project I have been working on. There are two halves of the project, the Client and the Server code.
The client needs two libraries I've made. The first is a general purpose game board. This is split between GameEngine.h and GameEngine.cpp. The header file looks something like this
namespace gfdGaming {
// struct sqr_size {
// Index x;
// Index y;
// };
typedef struct { Index x, y; } sqr_size;
const sqr_size sPos = {1, 1};
sqr_size sqr(Index x, Index y);
sqr_size ePos;
class board
{
// Prototypes / declarations for the class
}
}
And the CPP file is just giving everything content
#include "GameEngine.h"
type gfdGaming::board::functions
The client also has game-specific code (in this case, TicTacToe) split into declarations and definitions (TTT.h, Client.cpp). TTT.h is basically
#include "GameEngine.h"
#define TTTtar "localhost"
#define TTTport 2886
using namespace gfdGaming;
void* turnHandler(void*);
namespace nsTicTacToe
{
GFDCON gfd;
const char X = 'X';
const char O = 'O';
string MPhostname, mySID;
board TTTboard;
bool PlayerIsX = true, isMyTurn;
char Player = X, Player2 = O;
int recon(string* datHolder = NULL, bool force = false);
void initMP(bool create = false, string hn = TTTtar);
void init();
bool isTie();
int turnPlayer(Index loc, char lSym = Player);
bool checkWin(char sym = Player);
int mainloop();
int mainloopMP();
}; // NS
I made the decision to put this in a namespace to group it instead of a class because there are some parts that would not work well in OOP, and it's much easier to implement later on.
I have had trouble linking the client in the past, but this setup seems to work.
My server is also split into two files, Server.h and Server.cpp.
Server.h contains exactly:
#include "../TicTacToe/TTT.h" // Server needs a full copy of TicTacToe code
class TTTserv;
struct TTTachievement_requirement {
Index id;
Index loc;
bool inUse;
};
struct TTTachievement_t {
Index id;
bool achieved;
bool AND, inSameGame;
bool inUse;
bool (*lHandler)(TTTserv*);
char mustBeSym;
int mustBePlayer;
string name, description;
TTTachievement_requirement steps[safearray(8*8)];
};
class achievement_core_t : public GfdOogleTech {
public: // May be shifted to private
TTTachievement_t list[safearray(8*8)];
public:
achievement_core_t();
int insert(string name, string d, bool samegame, bool lAnd, int lSteps[8*8], int mbP=0, char mbS=0);
};
struct TTTplayer_t {
Index id;
bool inUse;
string ip, sessionID;
char sym;
int desc;
TTTachievement_t Ding[8*8];
};
struct TTTgame_t {
TTTplayer_t Player[safearray(2)];
TTTplayer_t Spectator;
achievement_core_t achievement_core;
Index cTurn, players;
port_t roomLoc;
bool inGame, Xused, Oused, newEvent;
};
class TTTserv : public gSserver {
TTTgame_t Game;
TTTplayer_t *cPlayer;
port_t conPort;
public:
achievement_core_t *achiev;
thread threads[8];
int parseit(string tDat, string tsIP);
Index conCount;
int parseit(string tDat, int tlUser, TTTplayer_t** retval);
private:
int parseProto(string dat, string sIP);
int parseProto(string dat, int lUser);
int cycleTurn();
void setup(port_t lPort = 0, bool complete = false);
public:
int newEvent;
TTTserv(port_t tlPort = TTTport, bool tcomplete = true);
TTTplayer_t* userDC(Index id, Index force = false);
int sendToPlayers(string dat, bool asMSG = false);
int mainLoop(volatile bool *play);
};
// Other
void* userHandler(void*);
void* handleUser(void*);
And in the CPP file I include Server.h and provide main() and the contents of all functions previously declared.
Now to the problem at hand
I am having issues when linking my server. More specifically, I get a duplicate symbol error for every variable in nsTicTacToe (and possibly in gfdGaming as well). Since I need the TicTacToe functions, I link Client.cpp ( without main() ) when building the server
ld: duplicate symbol nsTicTacToe::PlayerIsX in Client.o and Server.o
collect2: ld returned 1 exit status
Command /Developer/usr/bin/g++-4.2 failed with exit code 1
It stops once a problem is encountered, but if PlayerIsX is removed / changed temporarily than another variable causes an error
Essentially, I am looking for any advice on how to better organize my code to hopefully fix these errors.
Disclaimers:
-I apologize in advance if I provided too much or too little information, as it is my first time posting
-I have tried using static and extern to fix these problems, but apparently those are not what I need
Thank you to anyone who takes the time to read all of this and respond =)
You get error about duplicate definitions because that's what you have: each time a .cpp file includes TTT.h, a global bool PlayerIsX is defined (in the nsTicTacToe namespace, but still global). In this case, it's Server.cpp and Client.cpp that are including it.
One way to solve this could be to change the definitions into declarations by using extern, then doing the actual definition in a corresponding .cpp file (TTT.cpp, for instance).
In TTT.h:
namespace nsTicTacToe {
...
extern bool PlayerIsX;
...
}
In TTT.cpp:
#include "TTT.h"
bool nsTicTacToe::PlayerIsX;
and so on for the other definitions.
By the way, remember to have proper guard #ifdefs:
#ifndef __TTT_H
#define __TTT_H
... header contents
#endif // __TTT_H
Actually, extern IS what you need. You're probably just not realizing or remembering that you'll also have to define such variables in a cpp file.
header:
extern int somevar;
source:
int somevar = ?;
By putting all of your globals in the header you're making copies of them everywhere you include them, which is exactly what your compiler is bitching about.
You are essentially using globals, which is strongly not recommended in C++, but is sometimes necessary in C.
You could get it working with extern, but the "better" answer would be to wrap your globals in a state object of some sort.
struct State
{
GFDCON gfd;
const char X;
const char O;
string MPhostname, mySID;
board TTTboard;
bool PlayerIsX, isMyTurn;
char Player, Player2;
};
Create your state object in Main and pass it to each function that needs to know the state of the game system.
This will lead to much better code organization in the long run.
you could put the namespace nsTicTacToe part into it's own .cpp file, compile it separately and link it in.
You might also need a header file which just declares externs for the variables, and include that in you client and server .cpp files.

C++ CppUnit Test (CPPUNIT_ASSERT)

I'm trying to do up a screen scraping assignment. My cpp works, but I don't know how to integrate my unit testing. I tried to do a bool check unit test for the file validity but it's giving me this error:
error: cannot call member function 'bool ScreenScrape::getFile()' without object
screenscrape.cpp:
#include "screenscrape.h"
using namespace std;
int main()
{
ScreenScrape ss;
int choice;
...
...
ss.matchPatternTest();
}
screenscrape.h:
class ScreenScrape
{
public:
ScreenScrape();
void parserTest(int choice);
void matchPatternTest();
void setIndexValue(string data, string IndexName);
void setIndexChange(string data);
void setIndexPercent(string data);
void setIndexDate(string data);
bool getFile();
private:
string IndexName;
string IndexValue;
string IndexChange;
string IndexPercent;
string IndexVID;
string IndexCID;
string IndexPID;
string IndexDate;
};
bool ScreenScrape::getFile()
{
string file1 = "yahoofinance.htm";
char* file2 = new char [file1.size()+1]; // parse file for c string conversion
strcpy(file2, file1.c_str()); // converts to c string
ifstream fin;
fin.open(file2);
if(fin.good())
return true;
else
return false;
}
screenscrapetest.cpp:
#include "screenscrapetest.h"
#include "screenscrape.h"
CPPUNIT_TEST_SUITE_REGISTRATION (ScreenScrapeTest);
void ScreenScrapeTest::fileTest()
{
CPPUNIT_ASSERT(ScreenScrape::getFile()); // test file validity
}
screenscrapetest.h:
#ifndef _SCREENSCRAPETEST_H
#define _SCREENSCRAPETEST_H
#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>
#include "screenscrape.h"
class ScreenScrapeTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE (ScreenScrapeTest);
CPPUNIT_TEST (fileTest);
CPPUNIT_TEST_SUITE_END ();
public:
void fileTest();
};
#endif
I tried to declare "ScreenScrape ss;" under screenscrapetest.h, use an object (ss) to call getFile() but it's giving me multiples of this error:
/home/user/NetBeansProjects/Assignment1/screenscrape.h:259: multiple definition of `ScreenScrape::getFile()'
I only want to check for file validity with unit testing. Any help will be appreciated.
Thanks in advance!
Regards,
Wallace
bool ScreenScrape::getFile() is not static, so cannot be called as a static function. You'll need to either (a) declare it as static or (b) create an instance of ScreenScrape and call getFile() from it.
Looking at the code, it's not obvious why this function is a method of the class but perhaps it's still in the early stages of development. It can also be refactored to remove lots of redundant code:
bool ScreenScrape::getFile()
{
std::ifstream fin("yahoofinance.htm");
return fin.good();
}
Don't forget your include guards in screenscrape.h:
#ifndef SCREENSCRAPE_H
#define SCREENSCRAPE_H
// Class declaration here...
#endif//ndef SCREENSCRAPE_H
And consider moving the implementation of getFile to the cpp source file. These two steps will prevent you getting the "multiple declaration" errors.
This will fix your compilation errors, but checking for file validity is not a responsibility of a unit test. Unit tests should not interact with the filesystem.
If you're going to be calling ScreenScrape::getfile()rather than ss.getfile(), then getfile() needs be defined as static. The error you're getting is because non-static methods need to be called on a specific object.
It's difficult to track down the error with your version that defines a ScreenScrape object and then uses that to call getfile(); you obviously haven't included all the relevant code since your screenscrape.h file doesn't have 259 lines, and you also haven't shown the revised code in which you "use an object (ss) to call getFile()".