Undefined reference to a function when linking with g++ - c++

I am trying to link several object files and I am getting 3 undefined reference to a function errors.
inputtest.cpp
//test of input methods
#include <iostream>
#include <string>
#include <fstream>
#include <string>
#include <vector>
#include "Vector.h"
#include "Particle.h"
#include "read_particle_input.h"
#include "User_input.h"
#include "Particle_vector.h"
using namespace std;
using namespace berger_DEM;
int main() {
Particle_vector particles;
User_input input_data;
read_particle_input(particles, input_data);
cout <<endl<< particles.getpart(1).rho()<<endl<<particles.getpart(1).radius()<<endl;
return 0;
}
I am linking it with 5 object files with the names found in the ".h" files(just .o files compiled from .cpp files of the same name). One of the errors I receive is
undefined reference to 'berger_DEM::read_particle_input(berger_DEM::Particle_vector&, berger_DEM::User_input&)
note that this function has a prototype in read_particle_input.h and is implemented in read_particle_input.o. I am also getting two other undefined references, but I believe they are the same issue and if i can solve this one, the same solution should work for those two.
prototype:
namespace berger_DEM
{
void read_particle_input(Particle_vector&,User_input&);
}
implementation:
//method to read in particle_input.dat
void read_particle_input(Particle_vector & particles, User_input & input_data)
{
//define local variables
Vector velocity_in;
Vector position_in;
double radius_in;
double rho_in;
//open file and define file pointer
std::ifstream particle_input ("particle_input.dat");
//go through each line in particle_input.dat and define each particle
if (particle_input.is_open()) {
for(int i=0;i<input_data.num_particles();i++) {
//read one line from particle_input.dat
particle_input >> position_in;
particle_input >> radius_in;
particle_input >> rho_in;
particle_input >> velocity_in;
//set particle properties and position/velocity
particles.getpart(i).setrho(rho_in);
particles.getpart(i).setradius(radius_in);
particles.getpart(i).move(position_in);
particles.getpart(i).accelerate(velocity_in);
}
}
//close file
particle_input.close();
}
I've been looking all over for someone who had the same issue, but I was unable to find anything.
Thanks for the help.

Your implementation is missing the class scope.
change
void read_particle_input(Particle_vector & particles, User_input & input_data)
{
//define local variables
to
void berger_DEM::read_particle_input(Particle_vector & particles, User_input & input_data)
{
//define local variables

In implementation file it should be defined as,
void berger_DEM::read_particle_input(Particle_vector& particles, User_input& input_data);
{// ^^^^^^^^^^^ specify that 'read_particle_input' is part of the namespace
//...
}

Related

How can I split a file?

I was trying a code for splitting a file
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
int dim,k=1;
double x,y,x1,y1;
vector<double> AUX1[0],AUX2[0];
string file="ne_1417.dat",number;
ifstream IN(file);
while(IN >> x >> y)
{
AUX1.push_back(x);
AUX2.push_back(y);
}
IN.close();
dim=AUX1.size();
number=to_string(k);
ofstream OUT(number+file);
for(int i=0;i<dim;i++)
{
OUT<<AUX1[i]<<" "<<AUX2[i]<<endl;
if((AUX1[i+1]-AUX1[i])>50.){
k++;
number=to_string(k);
OUT.close();
ofstream OUT(number+file);
}
}
return 0;
}
I get the number of files I want but only the first file is full of data, the others are empty and I can't understand why =(
I need help, please <3
The problem is a matter of scoping and variable shadowing.
You have a variable named OUT in the function scope, defined before the writing loop. Then inside the if you define a new and totally different variable named OUT as well. When the scope of the block ends, so does the life-time of the new variable, and it is destructed.
You should not define a new variable, but rather reopen the existing file:
if((AUX1[i+1]-AUX1[i])>50.){
k++;
number=to_string(k);
OUT.close();
OUT.open(number+file); // Open the new file
}
All of the large compilers should be able to detect the variable shadowing and issue warnings about it. If you don't get such a warning then you need to enable more warnings (I recommend -Wall -Wextra -Wpedantic for GCC and Clang, and /W4 for VC++).

Error messages (multiple defined symbols) after including a class file

I am using the g++ compiler on a linux mint.
I´m tying to make a class for neural Network witch i want play tic tac toe.
My Header:
#ifndef tttAi
#define tttAi
#include <string>
class Synaps{
public:
explicit Synaps(const std::string& n, double v);
void add(double ad);
void multi(double mu);
void save();
double read();
private:
std::string name;
double Syn_value;
};
#endif
My functions are:
#include "tttAi.h"
#include <fstream>
#include <string>
Synaps::Synaps(const std::string& n, double v)
:name(n), Syn_value(v){
}
void Synaps::add(double ad) { //change by addition
Syn_value += ad;
}
void Synaps::multi(double multip) { //change by multiplication
Syn_value *= multip;
}
double Synaps::read() {
return Syn_value;
}
And here is what i wanted it to do:
#include <iostream>
#include "tttAi.h"
#include "tttAi.cpp"
int main() {
Synaps n1n6("n1n6", 75);
n1n6.multi(2);
std::cout << n1n6.read() << '\n';
/*Want it to just output the value of Syn_value Witch at
this point should be 150 if i have done everything right*/
}
Command used: g++ -Wall -std=c++14 *cpp
so what i would think i´d get was just the consol output of 150 but whilst compiling i get this endless error message:
enter image description here
hope you have a idea of what i did wrong, any ideas welcome.
You're including a cpp file containing definitions multiple times (i.e. you should not write
#include "tttAi.cpp"
in your main.cpp file) and therefore violating the ODR - one definition rule.
Remember that including a file means duplicating that file's contents in the point of inclusion (and therefore duplicating your definitions as well).
The problem seems to be #include "tttAi.cpp" in your main.cpp file.
You should not include cpp files
You should not #include .cpp files. Instead, just list them on the command line when you compile.

Passing an ifstream variable between members of the same object, C++

Goal: Using the class variable so that an ifstream declared in an object's member can be used by the following member of the same object, without having to use function header parameter passing.
Problem: The local ifstream of the created object test isn't being re-used in the second member of that object. I must be setting it up wrong, how do I fix this?
Classes and files feel like climbing a mountain to me right now, but I can't even find the first foothold - getting the blasted variable to work! I looked around the net for too long but all examples are convoluted, I just want to have something basic working to start tinkering with. I'm dead sure it's something stupidly easy that I'm missing, really frustrating >:[
main.cpp
#include "file.h
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
file test;
test.file_pass();
return 0;
}
file.h
#ifndef FILE_H
#define FILE_H
#include <fstream>
#include <iostream>
using namespace std;
class file
{
public:
file();
void file_pass();
//private:
ifstream stream;
};
#endif
file.cpp
#include "file.h"
//**********************************
//This will read the file.
file::file()
{
ifstream stream("Word Test.txt");
}
//**********************************
//This will output the file.
void file::file_pass()
{
//ifstream stream("Word Test.txt"); //if line activated, program works fine of course.
string line;
while(getline(stream, line))
cout << line << endl;
}
Here you are creating a new local variable with the same name as the class member:
file::file()
{
ifstream stream("Word Test.txt");
}
Instead you can use this to initialize the class member in the constructor:
file::file() : stream("Word Test.txt")
{
}

How to pass loaded struct array to other function in multiple file (c++)

On my mainfile, I wish to pass my loaded struct array from first function to second function ,both functions are in the source file(in.cpp). I was not able to do so even if I defined struct on main file, because firstly array cannot be return only pass by reference; I tried pass by reference also but does not work
#include "internetUsage.h"
#include "abc.h"
#include<fstream>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
char filename[20];
ifstream infile;
cout<<"enter file name: \n";
cin.getline(filename,20);
infile.open(filename);
newRecord(infile,filename);
updateRecord(infile,filename);
return 0;
}
This is my source file (in.cpp); after I loaded my struct array in my first function, I could not figure out how to display on my second function(updateRecord())
#include "internetUsage.h"
#include "abc.h"
#include <fstream>
#include<iostream>
using namespace std;
void newRecord(ifstream &infile,char filename[])
{
Info customer[50];
for(int i; i<6; i++)
{
infile>>customer[i].num;
infile>>customer[i].name;
infile>>customer[i].name2;
infile>>customer[i].charge;
}
}
void updateRecord(ifstream &infile,char filename[])
{
for(int j; j<6; j++)
{
cout<<customer[j].num<<endl;
cout<<customer[j].name<<endl;
cout<<customer[j].name2<<endl;
cout<<customer[j].charge<<endl;
}
}
This is my header file for two functions(internetUsage.h)
#include <fstream>
#include<cstring>
#include<iostream>
using namespace std;
void newRecord(ifstream &infile, char filename[]);
void updateRecord(ifstream &infile,char filename[]);
This is my header file for struct(abc.h)
#include<iostream>
using namespace std;
struct Info
{
int num;
char name[200];
char name2[200];
double charge;
};
you should define it Info customer[50]; as global variable , not local variable
define Info customer[50]; in main(),
Change newRecord() interface to add two parameters: Info * customer, int sizeCustomer
Change newRecord() internal loop to control customer's overflow, something like "if(j >= sizeCustomer) break;"
Change newRecord() interface to return number of customers have been read
Change updateRecord() interface to add two parameters: const Info * customer, int actualCustomerSize
Change updateRecord() internal loop to run for actualCustomerSize only, for example by modifing for(;j!=actualCustomerSize;)
Make changes in main()
Enjoy
Declare that structure as global in the file where you are loading that structure and then use the extern keyword along with the structure name in all the files where you want to use that function.
DO check this link:
http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/

Including parameters when defining a class's member functions is returning an error

I have the following class definition, written in C++, residing in it's own header file (ManageFeed.h)
#include <string>
#include <fstream>
#include <iostream>
#include <cstring>
class ManageFeed
{
bool get_feed();
void format_feed();
bool refresh_feed();
int find_start_of_string(string tag, ifstream& rssfile);
public:
void display_feed_list();
void display_feed_item();
ManageFeed();
};
When I try to compile this code, I get the following error
custom-headers/ManageFeed.h:22: error: ‘string’ has not been declared
custom-headers/ManageFeed.h:22: error: ‘ifstream’ has not been declared
I find that I can successfully compile the code without any errors if I remove the parameters from the int find_start_of_string() function, but aren't the parameters required if data is to be passed into the function? If I try to call this function from main(), I receive the following error
reader.cpp:6: error: prototype for ‘void ManageFeed::find_start_of_string(std::string, std::ifstream&)’ does not match any in class ‘ManageFeed’
so they are clearly required for the function to be usable. The textbook I'm using has examples of class definitions in their own head files with parameters present, but there seems to be no other difference in the structure of my code, nor is there any explanation given for why the books code works and mine doesn't.
Question: Are the parameters not required in the definition (the function definitions in ManageFeed.cpp have parameters specified) or am I doing something wrong here?
If anybody's interested, here's my application file
#include "custom-headers/ManageFeed.h"
using namespace std;
ifstream rssfile;
const string tag;
void ManageFeed::find_start_of_string(string tag, ifstream& rssfile);
int main()
{
ManageFeed manage_example;
rssfile.open("rss.xml");
manage_example.find_start_of_string(tag, rssfile);
return 0;
}
and the implementation file for ManageFeed
#include "ManageFeed.h"
#include <iostream>
#include <string>
#include <cstring>
ManageFeed::ManageFeed()
{
}
/*
A function that will get the location of the RSS file from the user
*/
bool ManageFeed::get_feed()
{
cout << "Please specify the location of the feed: " << endl << endl;
cin >> feed_source;
return true;
}
void ManageFeed::store_feed()
{
ifstream source_feed;
source_feed.open(feed_source);
ifstream local_feed;
local_feed.open
(
"/../File System/Feed Source Files/Example Feed/Example Feed.xml"
);
local_feed << source_feed;
}
int ManageFeed::find_start_of_string(string tag, ifstream& rssfile)
{
bool return_value = false;
string line;
size_t found;
do
{
getline(rssfile, line, '\n');
found = line.find(tag);
if (found != string::npos)
{
return_value = true;
return found;
}
} while (!return_value && !rssfile.eof());
if (!return_value)
{
}
}
John has the right solution. Here is the reasoning.
Both string and ifstream live in a namespace called std. When you say string you are telling the compiler to look into the global namespace and find a token called string. There is no such thing. You have to tell the compiler where to find string.
To do so you can either prefix them with std::string and std::ifstream or you can add using namesapce std; at the top of your header file.
Looking a little more closely, you do have the using directive in you .cpp file, but you put it after you include the header. That means the compiler parses the header without the namespace and then parses the rest of the file with it. If you just move the using directive above the header include, it will also fix your problem. Note, however, that anything else using the header will also need to do that same. Thus, start your .cpp file this way:
using namespace std;
#include "custom-headers/ManageFeed.h"
Change:
int find_start_of_string(string tag, ifstream& rssfile);
to:
int find_start_of_string(std::string tag, std::ifstream& rssfile);
Aside: why were there so many questions just like this one today?