Unresolved External Symbol with a particular function in c++ - c++

I got the error message like the following:
Unresolved External Symbol error with calculatewinner Candidate
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
void headerforelection();
void getNamecalculatetotal(ifstream& in, string candidates[], double Votes[], double percentvotes[]);
void getNamecalculatetotal2(ifstream& in, string fname[], double Votes[], double percentvotes[]);
void allvotes(double []);
void Votesrecievedpercentage(ifstream& in, char Candidate[], double Votes[], string fname[], double percentvotes[]);
void Votesrecievedpercentage2(double Votes[], string fname[], double percentvotes[]);
void calculatewinner(string fname[], double Votes[]);
void headerforelection();
int main()
{
ifstream in = ifstream();
in.open("Votes.txt");
ofstream out = ofstream();
out.open("outputs.txt");
char winner();
char Candidate();
string fname[5];
double Votes[5];
double percentvotes[5];
double total = double();
headerforelection();
while (!in.eof())
{
getNamecalculatetotal(in, fname, Votes, percentvotes);
Votesrecievedpercentage2(Votes, fname, percentvotes);
}
allvotes(Votes);
calculatewinner(fname, Votes);
}
void getNamecalculatetotal(ifstream& in, string fname[], double Votes[], double percent[])
{
double total = double();
for (int i = 0; i < 5; i++)
{
in >> fname[i] >> Votes[i];
total = total + Votes[i];
}
for (int j = 0; j < 5; j++)
{
percent[j] = (Votes[j] / total) * 100;
}
}
void headerforelection()
{
std::cout << fixed << setfill(' ') << left << setw(10) << "Candidate"
<< right << setw(20) << setprecision(0) << "votes Recieved"
<< right << setw(20) << setprecision(2) << "% of Total Votes" << std::endl;
std::cout << endl;
}
void Votesrecievedpercentage2( double Votes[], string fname[], double percentvotes[])
{
for (int b = 0; b < 5; b++)
{
std::cout << fixed << setfill(' ') << left << setw(10) << fname[b]
<< right << setw(16) << setprecision(0) << Votes[b]
<< right << setw(16) << setprecision(2) << percentvotes << std::endl;
}
}
void allvotes(double Votes[])
{
double total = double();
for (int i = 0; i < 5; i++)
{
total = total + Votes[i];
}
std::cout << setfill(' ') << left << setw(22) << "Total" << setprecision(0) << total << std::endl;
}
void calculatewinner(string fname[], double Votes[])
{
{
int winner = 0;
for (int l = 0; l, 5; l++)
{
if (Votes[l] > Votes[winner])
{
winner = l;//3
}
}
}
char winner();
char Candidate();
std::cout << std::endl;
std::cout << Candidate << "Is The Winner" << fname << "." << std::endl;
}

First to answer your question, change these lines
char winner();
char Candidate();
everywhere in your code (in main as well as in calculatewinner) to the following:
char winner;
char Candidate;
By adding the paranthesis you are actually declaring a prototype to a function. Since you never define a function Candidate(void) the linker complains about the missing implementation. This would apply to char winner() also, but since you never use this "variable", the linker isn't concerned about this one.
Otherwise, your code is very broken. I am sure you are just learning C++, but your code is quite inconsistent in naming conventions as well as some other errors that should be addressed before doing something else.

Related

simplify my code in C++ below

I want to create a program which is able to calculate the surface area, volume, and circumference. for your additional info, I am studying about function, I has just learned about C++ about a week.
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int getPostP(string msgP)
{
int Ppost= 0.000;
do
{
cout << msgP << endl;
cin >> Ppost;
return Ppost;
} while(Ppost<= 0);
}
int getPostL(string msgL)
{
int Lpost= 0.000;
do
{
cout << msgL << endl;
cin >> Lpost;
return Lpost;
} while(Lpost<= 0);
}
int getPostT(string msgT)
{
int Tpost = 0.000;
do
{
cout << msgT << endl;
cin >> Tpost;
return Tpost;
} while(Tpost <= 0);
}
int surfaceArea(int Psur, int Lsur, int Tsur)
{
return (2*Psur*Lsur)+(2*Psur*Tsur)+(2*Lsur*Tsur);
}
int volume(int Pvol, int Lvol, int Tvol)
{
return (Pvol*Lvol*Tvol);
}
float circumference(int Pcir, int Lcir, int Tcir)
{
return 4*(Pcir+Lcir+Tcir);
}
int main()
{
int P = getPostP("enter the P of your block");
int L = getPostL("enter the L of your block");
int T = getPostT("enter the T of your block");
float surfAreaBlock = surfaceArea(P, L, T);
float volBlock = volume(P, L, T);
float cirBlock = circumference(P, L, T);
cout << "block which have P = " << P << " and L = " << L << " and T = "<< T << " have surface area = " <<
surfAreaBlock << " and volume = " << volBlock << " and cirBlock = " << cirBlock;
return 0;
}
Maybe one of you want to rewrite and add some comment, which parts are able to simplify, so I can understand easier.
First of all, it looks like you should make all of your integer inputs into double instead of int, since it's expected that your inputs won't necessarily be an exact integer amount (probably). Also you can get rid of all of your duplicate functions for entering the parameters. Change it to a single function and call that one for each variable.
double getInput(const std::string& prompt)
{
double input(0.0);
do
{
std::cout << prompt << "\n-> " << std::flush;
// forces input to be a double type
while (!(std::cin >> input))
{
std::cout << "\n-> " << std::flush;
std::cin.clear();
std::cin.ignore(256, '\n'); ///< could use streamsize::max here
}
} while (input <= 0.0); ///< make sure it's positive
return input;
}

Using Pointers in functions

I am trying to use a pointer in my function and then call the function from my main body. When I try to call it I get these 2 errors'; "undefined reference to string output which is caused by the line where I call my stringOutput(); function and the other error is "Id returned 1 exit status." I'm not sure why these errors are occurring.
void stringOutput(int dayNumber, double *ptrTemperatures);
int main()
{
int dayNumber;
double fahrenheit = 0;
double cTemperature = 0;
const double MAXIMUM_TEMPERATURE = 60;// constants for mix/max
const double MINIMUM_TEMPERATURE = -90 ;
const int MAXIMUM_DAYS = 365;
const int MINIMUM_DAYS = 1;
double *ptrTemperatures = NULL;
cout << "How many days would you like to enter? ";
dayNumber = myValidation::GetValidInteger(MINIMUM_DAYS, MAXIMUM_DAYS);
try
{
ptrTemperatures = new double[dayNumber];
}
catch(exception e)
{
cout << "Failed to allocate memory: " << e.what() << endl;
}
cout << "\n\nTEMPERATURE REPORTER\n____________________________\n Please Enter the temperature for each day.";
for(int dayCount = 0; dayCount < dayNumber; dayCount++){
cout << "Celsius Temperature for Day " << (dayCount + 1) << ": ";
ptrTemperatures[dayCount] = myValidation::GetValidDouble(MINIMUM_TEMPERATURE, MAXIMUM_TEMPERATURE);
}
stringOutput();
delete[] ptrTemperatures;
return 0;
}//end main
void stringOutput(int dayNumber, double *ptrTemperatures)
{
cout << "DAILY TEMPERATURE REPORT\n__________________________________-\n\n";
for(int dayCounter = 0; dayCounter < dayNumber; dayCounter++)
{
cout << "Day " << dayCounter << (dayCounter+1) << setw(10) << celsiusToFahrenheit(ptrTemperatures[dayCounter]) << (char(248)) << "F"
<< setw(10) << ptrTemperatures[dayCounter] << (char(248)) << "C" << endl;
}
}
At a guess, your code looks roughly like this:
void stringOutput();
int main()
{
…
stringOutput();
}
void stringOutput(int dayNumber, double *ptrTemperatures)
{
…
}
Your main function uses the stringOutput function you declared above, but that function is never defined anywhere, hence the error.
Below main, you declare and define a separate overload of stringOutput, which has two parameters instead of none.
If you want to use the function you have below main, you need to declare it before main:
void stringOutput(int dayNumber, double *ptrTemperatures);
int main()
…
You also need to give it the arguments it needs, instead of giving it nothing:
int main()
{
…
stringOutput(dayNumber, ptrTemperatures);
}

Doesn't seem to be working using ifstream fin; and fin.open("filename");

I have a program for my class to read in information from a file, as an array, using a function and I've coded this the same way I did for classes last year and I'm not sure why it's not working. I'm supposed to also add more to this but wanted to try to figure out why it's not working with what it already has.
I don't think it's reading the file in because nothing comes out on the output file or the window that pops up when it runs.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
const int maxs = 50;
struct stype
{
int crn;
string name;
int crhrs;
int numstu;
int stucrhrs;
string prof;
};
stype initrec = { 0.0, "course", 0.0, 0.0, 0.0, "prof" };
void initem(stype p[], int &numc)
{
int i;
for (i = 0; i < maxs; i++) p[i] = initrec;
numc = 0;
}
void readem(stype p[], int &numc)
{
int i = 0;
ifstream fin;
fin.open("program1.dat");
while (!fin.eof())
{
fin >> p[i].crn >> p[i].name >> p[i].crhrs >> p[i].numstu >> p[i].stucrhrs >> p[i].prof;
i++;
}
numc = i;
cout << "readem reached " << endl;
}
void printem(stype p[], int &numc, ofstream &fout)
{
int i;
for (i = 0; i < numc; i++)
{
fout << left << setw(10) << p[i].crn << left << setw(15) << p[i].name << left
<< setw(15) << p[i].numstu << right << setw(2) << p[i].crhrs << right <<
setw(2) << p[i].stucrhrs << right << setw(10) << p[i].prof << endl;
}
cout << "printem reached " << endl;
}
void swapem(stype &a, stype &b)
{
stype temp;
temp = a;
a = b;
b = temp;
cout << "swapem reached " << endl;
}
void sortem()
{
cout << "sortem reached " << endl;
}
void getaverage()
{
cout << "getaverage reached " << endl;
}
void credithours()
{
cout << "Credit hours totalled. " << endl;
}
void main()
{
int crn[maxs], crhrs[maxs], stucrhrs[maxs];
string name[maxs], prof[maxs];
stype p[maxs];
int numc;
ofstream fout;
fout.open("program1.out");
fout.setf(ios::fixed);
fout.precision(2);
initem(p, numc);
readem(p, numc);
printem(p, numc, fout);
getaverage();
sortem();
printem(p, numc, fout);
system("pause");
}

Dynamic Allocation. No idea what these errors mean

This is a project in which I had to dynamically create an array of structs. No idea what these errors mean or what is wrong with my code.
Based on the advice given so far here most of my problems have been solved. Here is the short list of remaining errors.
/tmp/ccdjbURO.o: In function `main':
assignment8.cpp:(.text+0x5a): undefined reference to `getData(menuItemType&, int&, std::basic_ifstream<char, std::char_traits<char> >&)'
assignment8.cpp:(.text+0x116): undefined reference to `showMenu(menuItemType, int)'
assignment8.cpp:(.text+0x1a5): undefined reference to `showMenu(menuItemType, int)'
assignment8.cpp:(.text+0x29f): undefined reference to `makeSelection(int&, int, int)'
assignment8.cpp:(.text+0x2eb): undefined reference to `printCheck(menuItemType, int, int)'
collect2: error: ld returned 1 exit status
Here are my function prototypes and definitions as requested. I see no difference in the function signatures in the prototypes and definition headings vs the formatting of any function calls in the body of my program.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
struct menuItemType
{
string menuItem;
double menuPrice;
};
const double TAX = 0.05;
const string FILE_NAME = "Ch9_Ex5Data.txt";
int getData(menuItemType&, int&, ifstream);
int makeSelection(int&, int, int);
void showMenu(menuItemType, int);
void printCheck(menuItemType, int, int);
void getInt(int&);
void getChar(char&);
//********************************************************************************
//* getData
//********************************************************************************
int getData(menuItemType* &menuList, int& listSize, ifstream& inFile)
{
inFile.open("Ch9_Ex5Data.txt");
inFile >> listSize;
if (inFile.fail())
return -1;
menuList = new menuItemType[listSize];
for(int i = 0; i < listSize; i++)
{
getline(inFile, menuList[i].menuItem);
inFile >> menuList[i].menuPrice;
if (inFile.fail())
return -1;
break;
}
122,1 47%
return 1;
}
//********************************************************************************
//* makeSelection
//********************************************************************************
int makeSelection(int* &orderList, int quantity, int index)
{
if ((orderList[index] + quantity) < 0)
{
cout << "Quantity selected makes total number ordered less than 0"
<< endl << endl;
return 1;
}
else
{
orderList[index] = orderList[index] + 1;
return -1;
}
}
//********************************************************************************
//* showMenu
//********************************************************************************
void showMenu(menuItemType *menuList, int listSize)
{
cout << fixed << showpoint << setprecision(2) << endl << endl
<< "------Today's Menu------" << endl;
for(int i = 0; i < listSize; i++)
{
cout << left << setw(18) << menuList[i].menuItem << "$ "
<< right << setw(4) << menuList[i].menuPrice << endl;
}
cout << "------------------------"
<< endl << endl;
}
//********************************************************************************
//* printCheck
//********************************************************************************
void printCheck(menuItemType *menuList, int *orderList, int listSize)
{
int taxDue = 0;
int amntDue = 0;
cout << fixed << showpoint << setprecision(2) << endl << endl
<< "------Your Reciept------" << endl;
for (int i = 0; i < listSize; i++)
{
if (orderList[i] > 0)
{
cout << left << setw(2) << orderList[i] << " "
<< setw(15) << menuList[i].menuItem
<< right << setw(5) << (orderList[i] * menuList[i].menuPrice)
<< endl;
amntDue += (orderList[i] * menuList[i].menuPrice);
}
}
210,1 73%
taxDue = amntDue * TAX;
amntDue = amntDue * (1 + TAX);
cout << endl << right << setw(17) << "Tax: $ "
<< setw(7) << taxDue
<< endl << right << setw(17) << "Amount Due: $ "
<< setw(7) << amntDue
<< endl
<< "------------------------" << endl << endl;
}
187,0-1 64%
The errors do look unfriendly, but the issues are simple.
You pass an ifstream in
int getData(menuItemType* &menuList, int& listSize, ifstream inFile)
by value, which implicitly tries to make copy of it.
I think its not possible to copy istream and ostream. You have to pass them by reference.
Also, as #PeterT said in comment, there is no version of getline you are tryng to invoke. Both default versions expect input and string as arguments.
Your forward declarations ARE different from the definitions. Replace them with something like this:
int getData(menuItemType*&, int&, ifstream&);
int makeSelection(int*&, int, int);
void showMenu(menuItemType*, int);
void printCheck(menuItemType*, int*, int);
void getInt(int&);
void getChar(char&);

reading double from a binary file (into a class) - decimals do not show

having trouble displaying the decimals after reading the data.
As the title says.. here are some code snippets.
the header for the student obj
class StudentRecordData
{
protected:
double Marks[MAX_COURSES];
unsigned int Age;
unsigned int ID;
unsigned int CourseCount;
char FirstName[LEN_FN];
char LastName[LEN_FN];
Course Courses[MAX_COURSES];
};
student header:
class Student : public StudentRecordData {
public:
double *getMarks();
unsigned int getAge();
unsigned int getID();
unsigned int getCourseCount();
char *getFirstName();
char *getLastName();
Course *getCourses();
double getAverage();
int operator < (Student &);
int operator < (const char &);
};
Student implementation (inherited the above)
#include "Student.h"
#include <iostream>
#include <cstring>
using namespace std;
double *Student::getMarks() {
return Marks;
}
unsigned int Student::getAge() {
return Age;
}
unsigned int Student::getID() {
return ID;
}
unsigned int Student::getCourseCount() {
return CourseCount;
}
char *Student::getFirstName() {
return FirstName;
}
char *Student::getLastName() {
return LastName;
}
Course *Student::getCourses() {
return Courses;
}
int Student::operator<(Student &s) {
int ret = 0;
int LNRet = strcmp(this->getLastName(), s.getLastName());
int FNRet = strcmp(this->getFirstName(), s.getFirstName());
if (LNRet < 0) {
ret = 1;
} else if (LNRet == 0) {
if (FNRet < 0) {
ret = 1;
}
}
return ret;
}
int Student::operator<(const char &s) {
cout << "in char *!" << endl;
int ret = 0;
return ret;
}
double Student::getAverage() {
double total = 0.00;
for (int i = 0; i < (getCourseCount()); i++) {
total = total + getMarks()[i];
}
return total / getCourseCount();
}
the main
#include "Course.h"
#include "Student.h"
#include "Node.h"
#include "LinkedList.h"
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main(void) {
char input[] = "OOP344.dat";
char output[] = "OUTPUT.txt";
Student student;
LinkedList list;
Node *node;
// read in file
ifstream ifile(input, ios::binary);
while (!ifile.eof()) {
ifile.read(reinterpret_cast<char *>(&student), sizeof(Student));
node = new Node(student);
list.addNode(node);
}
ifile.close();
list.sort();
// write to file
ofstream ofile(output);
if (ofile.is_open()) {
for (node = list.getFirstNode(); node; node = list.getNextNode(node)) {
cout << setw(10) << "Last Name" << setw(12) << "First Name" << setw(5) << "Age" << setw(12) << "Student ID" <<
setw(15) << "Course" << setw(7) << "Mark" << endl;
cout << setw(10) << "=========" << setw(12) << "==========" << setw(5) << "===" << setw(12) << "==========" <<
setw(15) << "======" << setw(7) << "=====" << endl;
cout << setw(10) << node->getValue().getLastName()
<< setw(12) << node->getValue().getFirstName()
<< setw(5) << node->getValue().getAge()
<< setw(12) << node->getValue().getID()
<< setw(22) << node->getValue().getAverage()
<< endl;
int sem, sem_prev;
for (int i = 0; i < node->getValue().getCourseCount(); i++) {
sem = (int)node->getValue().getCourses()[i].Semester;
sem_prev = (int)node->getValue().getCourses()[i-1].Semester;
if (!(sem == sem_prev)) {
cout << setw(45) << "Sem " << (int)node->getValue().getCourses()[i].Semester << ":"
<< setw(7) << node->getValue().getCourses()[i].Name
<< setw(7) << setprecision(4) << node->getValue().getMarks()[i] << endl;
} else {
cout << setw(54) << node->getValue().getCourses()[i].Name
<< setw(7) << setprecision(4) << node->getValue().getMarks()[i] << endl;
}
}
cout << endl;
}
}
ofile.close();
return (0);
}
output:
Last Name First Name Age Student ID Course Mark
========= ========== === ========== ====== =====
Sakedad Roya 25 486503 74.31
Sem 1: APC100 69
EAC150 92
ICA002 76
IOS110 87
IPC144 99
Sem 2: ULI101 62
DBS201 66
IBC233 94
INT222 58
OOP244 67
Sem 3: DBS301 61
INT322 89
SYS366 52
BAC344 80
OOP344 63
Sem 4: DCN455 74
the problem is in this line near the bottom. it won't display any decimal points. any help is greatly appreciated.
setprecision(4) << node->getValue().getMarks()[i]
i can supply any other files which may be helpful. i'm just hoping my mistakes are somewhere in the main.
You've given us a lot of code to wade through for a simple
formatting issue, but I don't see where you tell the output
stream how you want the floating point values formatted. The
default formatting is defined so that it will result in
something readable for all possible values, but in practice,
it's never what you want for any particular set of values
(except maybe in log files or for serialization purposes). In
your case (and in a lot of smaller programs), you could probably
get by with just setting the floating point format to fixed:
ofile.setf( std::ios_base::fixed, std::ios_base::floatfield );
More generally, the best practice would be to define a
manipulator for the different semantic values you need: e.g.:
std::ostream&
mark( std::ostream& dest )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( 2 );
return dest;
}
You can then simply write:
ofile << ... << mark << node->getValue().getMarks()[i] << ...
Note, however, that both the format option and the precision are
sticky; they will remain set until changed. In any significant
code, it is a good practice to reset them to what they were
before.