An error I don't understand [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I'm getting this error when I compile, but I'm not sure how to fix it. I see that it has something to do with trying to use ofstream outFile; to write to a file. I've diddled with it, but I'm not sure what the problem is.
1>Rectangle.obj : error LNK2001: unresolved external symbol "class std::basic_ofstream<char,struct std::char_traits<char> > outFile" (?outFile##3V?$basic_ofstream#DU?$char_traits#D#std###std##A)
1>E:\Hw11_overload_Hw8\Debug\Rectangle.exe : fatal error LNK1120: 1 unresolved externals
This is my header file.
#ifndef Rectangle_h
#define Rectangle_h
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
class Rectangle
{
friend istream &operator>> (istream &input, Rectangle &grid);
friend ostream &operator<< (ostream &output, Rectangle grid);
private:
int i, j, h, x1, x2, y1, y2, perimeter, area, width, height;
char inner, outer;
string name;
public:
Rectangle();
void printGrid();
void setX1(int x11);
int getX1();
void setX2(int x21);
int getX2();
void setY1(int y11);
int getY1();
void setY2(int y21);
int getY2();
void setInner(char inner1);
char getInner();
void setOuter(char outer1);
char getOuter();
void findPerimeter();
void findArea();
void findWidth();
void findHeight();
void setName(string name1);
string getName();
int Menu();
};
#endif
And here is my source file.
#include "Rectangle.h"
extern ofstream outFile;
Rectangle::Rectangle()
{
x1 = 0;
x2 = 1;
y1 = 0;
y2 = 1;
}
void Rectangle::setX1(int x11)
{
x1 = x11;
}
int Rectangle::getX1()
{
return x1;
}
void Rectangle::setX2(int x21)
{
x2 = x21;
}
int Rectangle::getX2()
{
return x2;
}
void Rectangle::setY1(int y11)
{
y1 = y11;
}
int Rectangle::getY1()
{
return y1;
}
void Rectangle::setY2(int y21)
{
y2 = y21;
}
int Rectangle::getY2()
{
return y2;
}
void Rectangle::findPerimeter()
{
perimeter = ((x2 - x1) + (y2 - y1)) * 2;
cout << "The perimeter of the rectangle is: " << perimeter << endl;
}
void Rectangle::findArea()
{
area = (x2 - x1) * (y2 - y1);
cout << "The area of the rectangle is: " << area << endl;
}
void Rectangle::findWidth()
{
width = x2 - x1;
cout << "The width of the rectangle is: " << width << endl;
}
void Rectangle::findHeight()
{
height = y2 - y1;
cout << "The height of the rectangle is: " << height << endl;
}
void Rectangle::setInner(char inner1)
{
inner = inner1;
}
char Rectangle::getInner()
{
return inner;
}
void Rectangle::setOuter(char outer1)
{
outer = outer1;
}
char Rectangle::getOuter()
{
return outer;
}
void Rectangle::setName(string name1)
{
name = name1;
}
string Rectangle::getName()
{
return name;
}
void Rectangle::printGrid()
{
int numrows = 25;
int numcols = 25;
int current_row = numrows; // starting row number
int current_col = 1; // starting col number
char output = '.';
for(i = 0; i < numrows; i++) // prints 25 rows of 25 dots
{
cout << current_row << '\t'; // Print out current row number
outFile << current_row << '\t';
//This is out loop for each ROW
//Print out dots in each row OR stuff for the rectangle
for(j = 1; j <= numcols; j++) {
output = '.'; // Initialize output with our default value of "."
if ((current_col >= x1) && (current_col <= x2) && (current_row >= y1) && (current_row <= y2)) {
output = outer;
}
if ((current_col > x1) && (current_col < x2) && (current_row > y1) && (current_row < y2)) {
output = inner;
}
cout << output << " "; // output our "output" value and a space
outFile << output << " ";
current_col++; //Increment current column, because this is the end of this column loop iteration
} // Close column loop
cout << endl; //...and a new line
outFile << endl;
current_col = 1; // reset column count for next iteration
current_row--; // decrement current row number
} // Close Row loop
//output column labels across bottom line
cout << '\t';
outFile << '\t';
// put 1 -> 25 across the bottom
for (i = 1; i <= 25; i++)
{
if(i < 10)
{
cout << i << " ";
outFile << i << " ";
}
if(i > 9)
{
cout << i << " ";
outFile << i << " ";
}
}
// Spit out a couple of blank lines
cout << endl << endl;
outFile << endl << endl;
}
int Rectangle::Menu()
{
ifstream inFile;
int choice;
cout << "1. Enter information about a rectangle. " << endl;
cout << "2. Search for a rectangle. " << endl;
cout << "3. Print the perimeter and the area of the rectangle. " << endl;
cout << "4. Print the width and height of the rectangle. " << endl;
cout << "5. Draw a particular rectangle. " << endl;
cout << "6. Quit. " << endl;
cout << "Enter your choice. " << endl;
inFile >> choice;
cout << endl << endl;
return choice;
}
istream &operator>> (istream &input, Rectangle &grid)
{
ifstream inFile;
ofstream outFile;
Rectangle rect[10];
int x11, x21, y11, y21, choice, numRectangles = 0, i = 0;
char inner1, outer1;
string name1;
inFile.open ("rectangle.in");
outFile.open ("rectangle.out");
if (!inFile)
{
cout << "ERROR: inFile does not exist. " << endl;
system("pause");
}
if (!outFile)
{
cout << "ERROR: outFile does not exist. " << endl;
system("pause");
}
choice = rect[i].Menu();
while(choice >= 1 && choice <= 6)
{
if(choice == 1)
{ do
{
cout << "Enter x1, x2, y1, and y2 such that x1 < x2 and y1 < y2: " << endl;
inFile >> x11;
inFile >> x21;
inFile >> y11;
inFile >> y21;
cout << "Enter a character for the interior of the rectangle. \n";
inFile >> inner1;
cout << "Enter a character for the exterior of the rectangle. \n";
inFile >> outer1;
cout << "Enter a name for the rectangle. \n";
inFile >> name1;
rect[numRectangles].setX1(x11);
rect[numRectangles].setX2(x21);
rect[numRectangles].setY1(y11);
rect[numRectangles].setY2(y21);
rect[numRectangles].setInner(inner1);
rect[numRectangles].setOuter(outer1);
rect[numRectangles].setName(name1);
numRectangles++;
}
while(x11 >= x21 || y11 >= y21);
cout << endl << "Rectangle accepted. \n" << endl;
}
if (choice == 2)
{
cout << "To search for a rectangle, enter the name of the rectangle. " << endl;
cin >> name1;
for(i = 0; i < numRectangles; i++)
{
if(name1 == rect[i].getName())
{
rect[i].findPerimeter();
rect[i].findArea();
rect[i].findWidth();
rect[i].findHeight();
rect[i].printGrid();
system("pause");
}
}
if(name1 != rect[i].getName())
{
cout << "ERROR! Rectangle doesn't exist!" << endl << endl;
system("pause");
}
}
if(choice == 3)
{
for(i = 0; i < numRectangles; i++)
{
rect[i].findPerimeter();
cout << endl;
rect[i].findArea();
cout << endl;
}
}
if(choice == 4)
{
for(i = 0; i < numRectangles; i++)
{
rect[i].findWidth();
cout << endl;
rect[i].findHeight();
cout << endl;
}
}
if(choice == 5)
{
for(i = 0; i < numRectangles; i++)
{
rect[i].printGrid();
cout << endl;
}
}
if(choice == 6)
{
cout << "Bye bye!" << endl;
system("pause");
}
choice = rect[i].Menu();
return input;
} // End of while loop
inFile.close();
outFile.close();
}
ostream &operator<< (ostream &output, Rectangle grid)
{
return output;
}
And here is my main function
#include "Rectangle.h"
int main()
Rectangle rect[10];
int numRectangles;
for(int i = 0; i < numRectangles; i++)
{
cin >> rect[i];
cout << rect[i];
}
}

Problems:
You have declared that outFile will have external linkage. std::ofstream has no default constructor.
std::ofstream has a non-default constructor and takes two parameters.. The first is the location of the file and the second (which is default btw) is how you plan to open/write it.
Thus you can fix this error by replacing extern ofstream outFile; with:
ofstream outFile("output.txt"); within Rectangle.cpp
There is no need to declare it as extern within the .cpp file as far as I am aware.
Next, istream& operator>> (istream& input, Rectangle& grid) is returning NOTHING..
It should be returning input before the function finishes.
Finally, you are missing a curly bracket after main's () brackets.
You main.cpp should look like:
#include "Rectangle.h"
int main()
{
Rectangle rect[10];
int numRectangles;
for(int i = 0; i < numRectangles; i++)
{
cin >> rect[i];
cout << rect[i];
}
}
Would it really kill you to follow convention and format your code?
If done correctly, your code would look like:
Rectangle.h:
#ifndef Rectangle_h
#define Rectangle_h
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
class Rectangle
{
private:
friend istream& operator>> (istream& input, Rectangle& grid);
friend ostream& operator<< (ostream& output, Rectangle grid);
int i, j, h, x1, x2, y1, y2, perimeter, area, width, height;
char inner, outer;
string name;
public:
Rectangle();
void printGrid();
void setX1(int x11);
int getX1();
void setX2(int x21);
int getX2();
void setY1(int y11);
int getY1();
void setY2(int y21);
int getY2();
void setInner(char inner1);
char getInner();
void setOuter(char outer1);
char getOuter();
void findPerimeter();
void findArea();
void findWidth();
void findHeight();
void setName(string name1);
string getName();
int Menu();
};
#endif
Rectangle.cpp:
#include "Rectangle.h"
ofstream outFile("output.txt");
Rectangle::Rectangle()
{
x1 = 0;
x2 = 1;
y1 = 0;
y2 = 1;
}
void Rectangle::setX1(int x11)
{
x1 = x11;
}
int Rectangle::getX1()
{
return x1;
}
void Rectangle::setX2(int x21)
{
x2 = x21;
}
int Rectangle::getX2()
{
return x2;
}
void Rectangle::setY1(int y11)
{
y1 = y11;
}
int Rectangle::getY1()
{
return y1;
}
void Rectangle::setY2(int y21)
{
y2 = y21;
}
int Rectangle::getY2()
{
return y2;
}
void Rectangle::findPerimeter()
{
perimeter = ((x2 - x1) + (y2 - y1)) * 2;
cout << "The perimeter of the rectangle is: " << perimeter << endl;
}
void Rectangle::findArea()
{
area = (x2 - x1) * (y2 - y1);
cout << "The area of the rectangle is: " << area << endl;
}
void Rectangle::findWidth()
{
width = x2 - x1;
cout << "The width of the rectangle is: " << width << endl;
}
void Rectangle::findHeight()
{
height = y2 - y1;
cout << "The height of the rectangle is: " << height << endl;
}
void Rectangle::setInner(char inner1)
{
inner = inner1;
}
char Rectangle::getInner()
{
return inner;
}
void Rectangle::setOuter(char outer1)
{
outer = outer1;
}
char Rectangle::getOuter()
{
return outer;
}
void Rectangle::setName(string name1)
{
name = name1;
}
string Rectangle::getName()
{
return name;
}
void Rectangle::printGrid()
{
int numrows = 25;
int numcols = 25;
int current_row = numrows; // starting row number
int current_col = 1; // starting col number
char output = '.';
for(i = 0; i < numrows; i++) // prints 25 rows of 25 dots
{
cout << current_row << '\t'; // Print out current row number
outFile << current_row << '\t';
//This is out loop for each ROW
//Print out dots in each row OR stuff for the rectangle
for(j = 1; j <= numcols; j++)
{
output = '.'; // Initialize output with our default value of "."
if ((current_col >= x1) && (current_col <= x2) && (current_row >= y1) && (current_row <= y2))
{
output = outer;
}
if ((current_col > x1) && (current_col < x2) && (current_row > y1) && (current_row < y2))
{
output = inner;
}
cout << output << " "; // output our "output" value and a space
outFile << output << " ";
current_col++; //Increment current column, because this is the end of this column loop iteration
} // Close column loop
cout << endl; //...and a new line
outFile << endl;
current_col = 1; // reset column count for next iteration
current_row--; // decrement current row number
} // Close Row loop
//output column labels across bottom line
cout << '\t';
outFile << '\t';
// put 1 -> 25 across the bottom
for (i = 1; i <= 25; i++)
{
if(i < 10)
{
cout << i << " ";
outFile << i << " ";
}
if(i > 9)
{
cout << i << " ";
outFile << i << " ";
}
}
// Spit out a couple of blank lines
cout << endl << endl;
outFile << endl << endl;
}
int Rectangle::Menu()
{
ifstream inFile;
int choice;
cout << "1. Enter information about a rectangle. " << endl;
cout << "2. Search for a rectangle. " << endl;
cout << "3. Print the perimeter and the area of the rectangle. " << endl;
cout << "4. Print the width and height of the rectangle. " << endl;
cout << "5. Draw a particular rectangle. " << endl;
cout << "6. Quit. " << endl;
cout << "Enter your choice. " << endl;
inFile >> choice;
cout << endl << endl;
return choice;
}
istream& operator>> (istream& input, Rectangle& grid)
{
ifstream inFile;
ofstream outFile;
Rectangle rect[10];
int x11, x21, y11, y21, choice, numRectangles = 0, i = 0;
char inner1, outer1;
string name1;
inFile.open ("rectangle.in");
outFile.open ("rectangle.out");
if (!inFile)
{
cout << "ERROR: inFile does not exist. " << endl;
system("pause");
}
if (!outFile)
{
cout << "ERROR: outFile does not exist. " << endl;
system("pause");
}
choice = rect[i].Menu();
while(choice >= 1 && choice <= 6)
{
if(choice == 1)
{
do
{
cout << "Enter x1, x2, y1, and y2 such that x1 < x2 and y1 < y2: " << endl;
inFile >> x11;
inFile >> x21;
inFile >> y11;
inFile >> y21;
cout << "Enter a character for the interior of the rectangle. \n";
inFile >> inner1;
cout << "Enter a character for the exterior of the rectangle. \n";
inFile >> outer1;
cout << "Enter a name for the rectangle. \n";
inFile >> name1;
rect[numRectangles].setX1(x11);
rect[numRectangles].setX2(x21);
rect[numRectangles].setY1(y11);
rect[numRectangles].setY2(y21);
rect[numRectangles].setInner(inner1);
rect[numRectangles].setOuter(outer1);
rect[numRectangles].setName(name1);
numRectangles++;
}
while(x11 >= x21 || y11 >= y21);
cout << endl << "Rectangle accepted. \n" << endl;
}
if (choice == 2)
{
cout << "To search for a rectangle, enter the name of the rectangle. " << endl;
cin >> name1;
for(i = 0; i < numRectangles; i++)
{
if(name1 == rect[i].getName())
{
rect[i].findPerimeter();
rect[i].findArea();
rect[i].findWidth();
rect[i].findHeight();
rect[i].printGrid();
system("pause");
}
}
if(name1 != rect[i].getName())
{
cout << "ERROR! Rectangle doesn't exist!" << endl << endl;
system("pause");
}
}
if(choice == 3)
{
for(i = 0; i < numRectangles; i++)
{
rect[i].findPerimeter();
cout << endl;
rect[i].findArea();
cout << endl;
}
}
if(choice == 4)
{
for(i = 0; i < numRectangles; i++)
{
rect[i].findWidth();
cout << endl;
rect[i].findHeight();
cout << endl;
}
}
if(choice == 5)
{
for(i = 0; i < numRectangles; i++)
{
rect[i].printGrid();
cout << endl;
}
}
if(choice == 6)
{
cout << "Bye bye!" << endl;
system("pause");
}
choice = rect[i].Menu();
return input;
} // End of while loop
inFile.close();
outFile.close();
return input;
}
ostream& operator<< (ostream& output, Rectangle grid)
{
return output;
}
main.cpp:
#include "Rectangle.h"
int main()
{
Rectangle rect[10];
int numRectangles;
for(int i = 0; i < numRectangles; i++)
{
cin >> rect[i];
cout << rect[i];
}
}
I did not check anything else other than getting it to compile. That means I am not sure if you have any bugs preventing it from running correctly. I also would advice you to avoid using using namespace std; in header files.

Related

c++ when reading from a file i continualy get dirty memory in my array and in my file

we were supposed to create a program that can memorize drugs data for a farmacy we were supposd to make 3 function 1 for searching using the code 2 to show the understock in alphabetical description order and 3 to save and load the memorized data from a file called "dati.txt" but we ran in a dirty data problem the program write dirty data or read dirty data i can't figure out if is the loading or the writing pls help me
ps i'm new to programming and i m still learnign
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
#define Num 300
int n = 0;
FILE* file;
struct s_farmaci {
int codice;
string descrizione;
float prezzo;
int disponibilita;
};
void bubblesort(s_farmaci vet[], int num);
void sottoscorta(s_farmaci vet[], int tanti);
int ricercabin(s_farmaci vet[], int inizio, int fine, int codice);
int menu();
void caricamento(s_farmaci farmaco[]);
void mostrafarmaco(s_farmaci farmaco[], int indice);
void scambia(s_farmaci v[], int i, int j);
void salvahdd(s_farmaci farmaco[]);
void caricahdd(s_farmaci farmaco[]);
int main()
{
s_farmaci farmaco[Num];
int scelta;
int codicericerca;
int trovato = -1;
caricahdd(farmaco);
system("pause");
scelta = menu();
do
{
switch (scelta) {
case 4:
{
cout << "stai per uscire dal programma" << endl;
salvahdd(farmaco);
cout << "dati salvati correttamente correttamente" << endl;
break;
}
case 1:
{
caricamento(farmaco);
break;
}
case 2:
{
bubblesort(farmaco, n);
cout << "quale codice vuoi cercare? ";
cin >> codicericerca;
trovato = ricercabin(farmaco, 0, n - 1, codicericerca);
if (trovato == -1)
cout << "Prodotto non trovato!" << endl;
else {
cout << "prodotto trovato: " << endl;
mostrafarmaco(farmaco, trovato);
}
break;
}
case 3:
{
sottoscorta(farmaco, n);
break;
}
default:
{
cout << " errore scelta non valida riprova " << endl;
break;
}
}
system("pause");
scelta = menu();
} while (scelta != 0);
return 0;
}
//bubblesort of the code
void bubblesort(s_farmaci vet[], int num)
{
int tempcodice;
float tempprezzo;
int tempquantita;
string tempdescrizzione;
bool scambi = false;
do {
scambi = false;
for (int i = 0; i < num - 1; i++) {
if (vet[i].codice > vet[i + 1].codice) {
scambi = true;
tempcodice = vet[i].codice;
vet[i].codice = vet[i + 1].codice;
vet[i + 1].codice = tempcodice;
tempprezzo = vet[i].prezzo;
vet[i].prezzo = vet[i + 1].prezzo;
vet[i + 1].prezzo = tempprezzo;
tempquantita = vet[i].disponibilita;
vet[i].disponibilita = vet[i + 1].disponibilita;
vet[i + 1].disponibilita = tempcodice;
tempdescrizzione = vet[i].descrizione;
vet[i].descrizione = vet[i + 1].descrizione;
vet[i + 1].descrizione = tempdescrizzione;
}
}
} while (scambi == true);
}
//menu
int menu()
{
system("cls");
int scelta;
cout << "-----------------------------" << endl;
cout << "- BENVENUTI -" << endl;
cout << "-----------------------------" << endl;
cout << "- -" << endl;
cout << "- 1 caricamento -" << endl;
cout << "- 2 ricerca -" << endl;
cout << "- 3 mostra -" << endl;
cout << "- 4 salva -" << endl;
cout << "- -" << endl;
cout << "-----------------------------" << endl;
cout << "-- inserici numero: ";
cin >> scelta;
return scelta;
}
//get drugs information
void caricamento(s_farmaci farmaco[]) {
system("cls");
cout << "inserisci il " << n + 1 << " farmaco" << endl;
//inserisco il codice
cout << "insersci il codice: ";
cin >> farmaco[n].codice;
//inserisco la descrizione
cout << "inserisci la descrizione del farmaco: ";
cin.ignore();
getline(cin, farmaco[n].descrizione);
//inserisco il prezzo
cout << "inserici il prezzo: ";
cin >> farmaco[n].prezzo;
//inserico la disponibilita
cout << "inserci quanti farmaci sono disponibili: ";
cin >> farmaco[n].disponibilita;
cout << endl;
n++;
}
/show memorized drugs
void mostrafarmaco(s_farmaci farmaco[], int indice) {
cout << endl;
cout << "codice farmaco :" << farmaco[indice].codice << endl;
cout << "descrizione farmaco :" << farmaco[indice].descrizione << endl;
cout << "prezzo farmaco :" << farmaco[indice].prezzo << endl;
cout << "quantita disponibili :" << farmaco[indice].disponibilita << endl;
}
//binary search
int ricercabin(s_farmaci vet[], int inizio, int fine, int codice) {
int medio;
if (inizio > fine)
return -1;
else {
medio = (inizio + fine) / 2;
if (codice == vet[medio].codice)
return medio;
else
if (codice > vet[medio].codice)
return ricercabin(vet, medio + 1, fine, codice);
else
return ricercabin(vet, inizio, medio - 1, codice);
}
}
//show me understock
void sottoscorta(s_farmaci vet[], int tanti) {
int tempcodice;
float tempprezzo;
int tempquantita;
for (int x = 0; x < tanti; x++) {
//algoritmo di ordinamento
int i, j;
string temp;
//sorting farmacs description
for (j = 0; j < tanti - 1; j++)
for (i = 0; i < tanti - 1; i++)
if (vet[i].descrizione > vet[i+1].descrizione)
scambia(vet, i, i+1);
}
for (int k = 0; k < tanti; k++) {
if (vet[k].disponibilita < 3) {
cout << endl;
cout << " il codice del farmaco e':" << vet[k].codice << endl;
cout << " la descrizione del farmaco e':" << vet[k].descrizione << endl;
cout << " il prezzo del farmaco e':" << vet[k].prezzo << endl;
cout << " la disponibilita' del farmaco e':" << vet[k].disponibilita << endl;
}
}
}
//exchange variables
void scambia(s_farmaci v[], int i, int j) {
s_farmaci temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
//get file from hdd
void caricahdd(s_farmaci farmaco[]) {
n = 0;
if ((file = fopen("dati.txt", "rb")) == NULL)
cout << "errore apertura file" << endl;
else {
while (!feof(file)) {
fread(&farmaco[n], sizeof(s_farmaci), 1, file);
n++;
}
fclose(file);
cout << "dati caricati correttamente" << endl;
}
}
//save file on hdd
void salvahdd(s_farmaci farmaco[]) {
if ((file = fopen("dati.txt", "wb")) == NULL)
cout << "errore apertura file" << endl;
else {
for (int i = 0; i <= n; i++) {
fwrite(&farmaco[i], sizeof(s_farmaci), 1, file);
}
fclose(file);
}
}
You say read-file get dirty data in array;
But it's not dirty data
fread(&farmaco[n], sizeof(s_farmaci), 1, file);
It only means that, read some data and put in the address(&farmaco[n]).But C++ don't know how to correctly set the data for the member of the array.
For Example:
/*this is the data file*/
19 /*set age value*/
Hello /*set name value*/
20 /*set age value*/
Exam /*set name value*/
And a struct has two members
struct people
{
int age;
string name;
}
The array people[2],this is how to read data and set value
/*read the first data and set people[0].age*/
people[0].age = 19
/*read the second data and set people[0].name*/
people[0].name= Hello
/*read the third data and set people[1].age*/
people[1].age = 19
/*read the fourth data and set people[1].name*/
people[1].name= Hello
/*and so on*/

C++ undefined reference to `findGrossPay(employeeInfo, double, int)'

A class I've been working on for a few days, running into an error I'm unsure how to fix.
#include <iostream> // for cin, cout, endl
#include <string>
#include <iomanip> // formatting floats
using namespace std;
void programHeader();
void footer();
void printEmployeeInfo(struct employeeInfo);
struct employeeInfo
{
int employeeID;
char employeeName[20];
double payRate;
int employeeType;
};
float findGrossPay(employeeInfo myEmployee, double , int);
void payrollDisplay(employeeInfo myEmployee, double, double, double, float, float);
//prototype declerations
int main()
{
// decleration of variables
float inputNumber1;
int num1;
int num2;
int num3;
int num4;
employeeInfo myEmployee[4];
float totalGross;
float totalNet;
int maxName = 20;
int location;
double hoursArray[4];
double grossPay[4];
double tax[4];
double netPay[4];
// input section
programHeader();
num4 = 0;
location = 0;
for (int c = 0; c < 4; c++) // fill in the array of structs
{
while (true); // validation loop
{
cout << "Employee ID: ";
cin >> num1;
if (num1 > 0);
{
myEmployee[c].employeeID = num1;
break;
} // end if
if (num1 <= 0)
{
cout << "\nERROR PLEASE TRY AGAIN" << endl;
} // end else if
} // end while
cout << "Employee Name: ";
cin.getline(myEmployee[c].employeeName, maxName);
while (true); // validation loop
{
cout << "Pay rate: ";
cin >> num2;
if (num2 > 0);
{
myEmployee[c].payRate = num2;
break;
} // end if
if (num2 <= 0)
{
cout << "\nERROR PLEASE TRY AGAIN" << endl;
} // end if
} // end while
while (true) // validation loop
{
cout << "Type: ";
cin >> num3;
if ((num3 == 1) || (num3 == 0))
{
myEmployee[c].employeeType = num3;
break;
} // end if
else
{
cout << "\nERROR PLEASE TRY AGAIN" << endl;
} // end else
} // end while
} // end for(c)
for (int h = 0; h < 4; h++); // parallel array to hold hours worked
{
cout << "Hours worked for " << myEmployee[num4].employeeName << ": ";
cin >> hoursArray[num4];
num4 = num4 +1;
} // end for(h)
// calculation section
// displays the results
for (int l = 0; l < 4; l++) // l for location
{
grossPay[l] = findGrossPay(myEmployee[4], hoursArray[4], location);
location = location + 1;
} // end for(l)
for (int t = 0; t < 4; t++) // get taxes and net pay for each
{
tax[t] = grossPay[t] * (15 / 100);
netPay[t] = grossPay[t] - tax[t];
}
for (int i = 0; i < 4; i++)
{
totalGross = totalGross + grossPay[i];
totalNet = totalNet + netPay[i];
} // end of for
payrollDisplay(myEmployee[4], grossPay[4], tax[4], netPay[4], totalGross, totalNet);
footer();
system("PAUSE");
return 0;
}// end of main
float findGrossPay(employeeInfo myEmployee[4], double hoursArray[4], int l) // l stands for location
{
float numGrossPay;
if (myEmployee[l].employeeType == 1) // management
{
numGrossPay = myEmployee[l].payRate * hoursArray[l];
} // end if
else if (myEmployee[l].employeeType == 0) // union members
{
if (hoursArray[l] > 40)
{
numGrossPay = myEmployee[l].payRate * 40 + (hoursArray[l] - 40) * (myEmployee[l].payRate * 1.5);
} // end if
else
{
numGrossPay = myEmployee[l].payRate * hoursArray[l];
} // end else
} // end else if
return numGrossPay;
}
void payrollDisplay(employeeInfo myEmployee[4], double grossPay[4], double tax[4], double netPay[4], float totalGross, float totalNet)
{
cout << "------------------------------------------------------------" << endl;
cout << "\nPayroll Report\n" << endl;
cout << "ID \tName" << "\t\tGross Pay \tTax \tNet Pay" << endl;
for (int i = 0; i < 4; i++) // to print each employee
{
cout << myEmployee[i].employeeID << "\t" << myEmployee[i].employeeName << "\t\t" << grossPay[i]
<< "\t" << tax[i] << "\t" << netPay[i] << endl;
} // for(i)
cout << "\nTotal Gross Pay \t$" << totalGross << endl;
cout << "Total Net Pay \t$" << totalNet << endl;
}
It's giving me an error stating there is an undefined reference to these lines in main():
grossPay[l] = findGrossPay(myEmployee[4], hoursArray[4], location);
and
payrollDisplay(myEmployee[4], grossPay[4], tax[4], netPay[4], totalGross, totalNet);
The "undefined reference" errors are because your function declarations do not match their definitions.
You have declared findGrossPay() and payrollDisplay() as taking in a single employeeInfo and related values for that one employee, but then your definitions are taking in arrays of employees and values:
//declaration
float findGrossPay(employeeInfo myEmployee, double , int);
//definition
float findGrossPay(employeeInfo myEmployee[4], double hoursArray[4], int l)
// declaration
void payrollDisplay(employeeInfo myEmployee, double, double, double, float, float);
//definition
void payrollDisplay(employeeInfo myEmployee[4], double grossPay[4], double tax[4], double netPay[4], float totalGross, float totalNet)
As such, the linker can't find matching definitions for the functions you are actually calling.
And, to make that worse, the places where you are calling these functions are accessing array elements out of bounds, which is undefined behavior.
After you fix that problem, you should then get "undefined reference" errors for programHeader() and footer(), since their definitions are missing completely.
After fixing that, there are still other problems with your code:
you have a number of if and for/while loops that have an erroneous ; on them
you are accessing arrays incorrectly in some places
you have uninitialized variables in some of your calculations
With that said, try something more like this:
#include <iostream> // for cin, cout, endl
#include <string>
#include <iomanip> // formatting floats
#include <limits>
using namespace std;
struct employeeInfo
{
int employeeID;
string employeeName;
double payRate;
int employeeType;
};
//prototype declerations
void programHeader();
void footer();
int promptForNumber(const string &prompt, int minValue = 0, int maxValue = numeric_limits<int>::max());
string promptForString(const string &prompt);
float findGrossPay(const employeeInfo &myEmployee, double hours);
void payrollDisplay(const employeeInfo myEmployee[4], const double grossPay[4], const double tax[4], const double netPay[4]);
int main()
{
// decleration of variables
employeeInfo myEmployee[4];
double hours[4];
double grossPay[4];
double tax[4];
double netPay[4];
int num;
// input section
programHeader();
for (int c = 0; c < 4; c++) // fill in the array of structs
{
myEmployee[c].employeeID = promptForNumber("Employee ID", 1);
myEmployee[c].employeeName = promptForString("Employee Name");
myEmployee[c].payRate = promptForNumber("Pay rate", 1);
myEmployee[c].employeeType = promptForNumber("Type", 0, 1);
}
for (int h = 0; h < 4; h++) // parallel array to hold hours worked
{
hours[h] = promptForNumber("Hours worked for " << myEmployee[h].employeeName);
}
// calculation section
for (int l = 0; l < 4; l++) // l for location
{
grossPay[l] = findGrossPay(myEmployee[l], hours[l]);
}
for (int t = 0; t < 4; t++) // get taxes and net pay for each
{
tax[t] = grossPay[t] * (15 / 100);
netPay[t] = grossPay[t] - tax[t];
}
// displays the results
payrollDisplay(myEmployee, grossPay, tax, netPay);
footer();
system("PAUSE");
return 0;
}
void programHeader()
{
// print out something here...
}
void footer()
{
// print out something here...
}
int promptForNumber(const string &prompt, int minValue, int maxValue)
{
int num;
while (true) // validation loop
{
cout << prompt << ": ";
if (cin >> num)
{
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if ((num >= minValue && num <= maxValue)
break;
}
else
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << "\nERROR PLEASE TRY AGAIN" << endl;
}
return num;
}
string promptForString(const string &prompt)
{
string input;
while (true) // validation loop
{
cout << prompt << ": ";
if (getline(cin, input) && !input.empty())
break;
cout << "\nERROR PLEASE TRY AGAIN" << endl;
}
return input;
}
float findGrossPay(const employeeInfo &myEmployee, double hours)
{
if (myEmployee.employeeType == 1) // management
{
return myEmployee.payRate * hours;
}
// must be myEmployee.employeeType == 0 // union members
if (hours > 40)
{
return myEmployee.payRate * 40 + (hours - 40) * (myEmployee.payRate * 1.5);
}
else
{
return myEmployee.payRate * hours;
}
}
void payrollDisplay(const employeeInfo myEmployee[4], const double grossPay[4], const double tax[4], const double netPay[4])
{
float totalGross = 0.0f;
float totalNet = 0.0f;
cout << "------------------------------------------------------------" << endl;
cout << "\nPayroll Report\n" << endl;
cout << "ID \tName" << "\t\tGross Pay \tTax \tNet Pay" << endl;
for (int i = 0; i < 4; i++) // to print each employee
{
cout << myEmployee[i].employeeID << "\t" << myEmployee[i].employeeName << "\t\t" << grossPay[i] << "\t" << tax[i] << "\t" << netPay[i] << endl;
totalGross += grossPay[i];
totalNet += netPay[i];
}
cout << "\nTotal Gross Pay \t$" << totalGross << endl;
cout << "Total Net Pay \t$" << totalNet << endl;
}
That said, you might consider moving the hours/grossPay/tax/netPay values into the employeeInfo struct, so that you have to manage only 1 array and not 5 parallel arrays.

C++ My files were working before I attempted to move them into a source file, and now there are no errors and nothing being displayed

My apologies for being a little vague about the issue(s) in the topic, but I really am not sure. I am attempting to create a course_directory as a lab project for school, and up until now everything had been progressing quite well. I have written and tested each of the function in the main.cpp before attempting to move the class functions into the .hpp file. My goal is to have nothing in main except for a call to "Run" that will open a file, and in turn make a call to "displayMenu", and allow the user to interact with the information as they choose, but now everything is compiling correctly, and nothing is being displayed.
Course_directory.hpp
#include "Course_Directory.h"
using namespace std;
Course_Directory::Course_Directory(){};
Course_Directory courses[1001];
void Course_Directory::displayMenu(){
cout << "1.Print all courses" << endl;
cout << "2.Print all courses for a department" << endl;
cout << "3.Print roster for a course" << endl;
cout << "4.Print the largest class" << endl;
cout << "5.Swap two classes" << endl;
cout << "6.Print schedule for a student" << endl;
cout << "7.Exit" << endl;
char dept[50], dept2[50];
int courseNo, courseNo2, i, choice;
while (choice != 7) {
cout << "\nEnter your choice: ";
cin >> choice;
if (choice == 1)
printAllCourses(i);
else if (choice == 2) {
cout << "\nEnter department name:";
cin >> dept;
for(int j = 0; j < sizeof(dept); j++)
{
dept[j] = (toupper(dept[j]));
}
coursesInDept(dept, i);
}
else if (choice == 3) {
cout << "\nEnter course number:";
cin >> courseNo;
studentsInCourse(courseNo, i);
}
else if (choice == 4) {
largestClass(i);
}
else if (choice == 5) {
cout << "\nEnter first department name :";
cin >> dept;
for(int j = 0; j < sizeof(dept); j++)
{
dept[j] = (toupper(dept[j]));
}
cout << "\nEnter first course number: ";
cin >> courseNo;
cout << "\nEnter second department name :";
cin >> dept2;
for(int k = 0; k < sizeof(dept2); k++)
{
dept2[k] = (toupper(dept2[k]));
}
cout << "\nEnter second course number: ";
cin >> courseNo2;
swap2(dept, courseNo, dept2, courseNo2, i);
}
else if (choice == 6) {
int id;
cout << "\nEnter a student Id:";
cin >> id;
schedule(id, i);
}
}
cout << "Goodbye!\n";
}
void Course_Directory::printAllCourses(int len){
for (int i = 0; i < len; i++)
cout << "Course name: " << courses[i].courseName << ", Course
number: " << courses[i].courseNum << endl;
cout << len;
}
void Course_Directory::coursesInDept(char *dept, int len) {
for (int i = 0; i < len; i++)
if (strcmp(dept, courses[i].courseName) == 0)
cout << "Course Name: " << courses[i].courseName << ",
Course number: " << courses[i].courseNum << endl;
}
void Course_Directory::studentsInCourse(int courseNo, int len) {
for (int i = 0; i < len; i++)
if (courseNo == courses[i].courseNum) {
for (int m = 0; m < courses[i].numStudents - 1; m++)
cout << courses[i].IDs[m] << ",";
cout << courses[i].IDs[courses[i].numStudents - 1] <<
endl;
}
}
void Course_Directory::largestClass(int len) {
int max = -999;
for (int i = 0; i < len; i++) {
if (courses[i].numStudents > max)
max = courses[i].numStudents;
}
for (int i = 0; i < len; i++) {
if (courses[i].numStudents == max){
cout << "\nThe largest class is in department: " <<
courses[i].courseName
<< ", and the course number is: " << courses[i].courseNum
<< "\n";
cout << "The class currently has " << max << " students
enrolled.\n";
}
}
}
void Course_Directory::swap2(char *firstDep, int firstNo, char
*secondDep, int secondNo, int len) {
Course_Directory temp;
int firstIndex, secondIndex;
for (int i = 0; i < len; i++) {
if (strcmp(firstDep, courses[i].courseName) == 0 &&
courses[i].courseNum == firstNo)
firstIndex = i;
if (strcmp(secondDep, courses[i].courseName) == 0 &&
courses[i].courseNum == secondNo)
secondIndex = i;
}
temp = courses[firstIndex];
courses[firstIndex] = courses[secondIndex];
courses[secondIndex] = temp;
}
void Course_Directory::schedule(int id, int len) {
cout << "Courses student " << id << " is enrolled in: " << endl;
for (int i = 0; i < len; i++) {
for (int j = 0; j < courses[i].numStudents; j++)
if (courses[i].IDs[j] == id)
cout << courses[i].courseNum << " \n";
}
}
Course_Directory.h
#ifndef COURSE_DIRECTORY_H
#define COURSE_DIRECTORY_H
#include <iostream>
using namespace std;
class Course_Directory{
private:
int* deptSize;
string filename;
public:
char courseName[1001];
int courseNum;
int numStudents;
int IDs[1001];
int* choice;
void displayMenu();
Course_Directory();
//Course_Directory(const Course_Directory& original);
//~Course_Directory();
//void run(string);
void coursesInDept(char*, int);
void studentsInCourse(int, int);
void largestClass(int);
void swap2(char*, int, char*, int, int);
void schedule(int, int);
void printAllCourses(int);
};
#include "Course_Directory.hpp"
#endif //COURSE_DIRECTORY_H
main.cpp
#include "Course_Directory.h"
using namespace std;
class Course_Directory;
int main() {
ifstream file;
file.open("input.txt");
char *token;
int i = 0, j;
Course_Directory courses[100];
if (!file.fail()) {
std::string line;
while (getline(file, line)) {
j = 0;
char *str = const_cast<char *>(line.c_str());
token = strtok(str, " ");
while (token != NULL)
{
if (j == 0)
strcpy(courses[i].courseName, token);
else if (j == 1)
courses[i].courseNum = atoi(token);
else if (j == 2)
courses[i].numStudents = atoi(token);
else
courses[i].IDs[j - 3] = atoi(token);
j++;
token = strtok(NULL, " ");
cout << courses[i].courseName << endl;
}
i++;
}
file.close();
}
else{
cout << "File not found." << endl;
}
//menu
Course_Directory displayMenu();
return 0;
}
If I leave Course_Directory off of displayMenu(); then I get "displayMenu" was not declared in this scope. I'm not sure what the problem is or why the menu will not display. Any help would be greatly appreciated!

Counter adding items to array with remainder

I am creating an RPG shop. It must have items, gold, and item price. Essentially creating an inventory. What i am trying to accomplish is, where the players gold is 0 they cannot add any more items to their inventory, and cannot have negative gold.
When running my code in debug mode it appears to be doing what i want, but when the function exits the amount the player requested has not been countered.
Keep in mind i am still new to c++.
Thanks
#include <iostream>
#include <string>
using namespace std;
// Global consts
const int numItems = 4;
const string items[numItems] = {"boots", "hats", "cats", "bats"}; // create string array of numItems items.
// Create stuct, that holds:
// Item, gold, price.
struct Inv {
int pInv[numItems] = {0, 0, 0, 0};
int gold = 100;
int itemPrice[numItems] = { 10, 6, 12, 15 };
}inv;
void iniItems();
void printItems();
bool buyItems();
bool sellItems();
int main() {
bool isDone = false;
iniItems();
while (isDone == false) {
printItems();
int choice;
bool x = false;
cout << "\nWhat would you like to do? Enter (" << 1 << "-" << 2 << "): " << endl;
cout << "1: Buy Items. \n2: Sell Items." << endl; cin >> choice; cout << endl;
while (x == false) {
if (choice == 1) {
x = buyItems();
}
if (choice == 2) {
x = sellItems();
}
}
}
system("pause");
// dynamic memory not implemented yet. Must wait for working fix of shoppe.cpp
}
void iniItems() {
cout << "** Shop Inventory: **" << endl;
for (int i = 0; i < numItems; i++) {
cout << i + 1 << " - " << items[i] << " - price: $" << inv.itemPrice[i] << endl;
}
}
void printItems() {
cout << "\n** Player Inventory: **" << endl;
cout << "Gold: $" << inv.gold << endl;
for (int i = 0; i < numItems; i++) {
cout << inv.pInv[i] << " x " << items[i] << endl;
}
}
bool buyItems() {
bool exit = false;
int amount;
const int remainder = 10;
printItems();
cout << "\nEnter -1 to quit." << endl;
cout << "What would you like to buy? Enter (" << 1 << "-" << 4 << "): " << endl;
// Get item info.
while (exit == false) {
int inp;
cout << "Item: "; cin >> inp; cout << endl;
cout << "Amount: "; cin >> amount; cout << endl;
// Check if input is valid.
if (inp > 0 && inp <= numItems) {
if (amount >= 0) {
inv.pInv[inp - 1] = 1 * amount;
inv.gold = inv.itemPrice[inp - 1] / amount;
}
// If gold is 0, make sure the user cannot gain more items.
if (inv.gold <= 0) {
int tmp;
inv.gold = 0;
tmp = remainder - amount;
for (int i = tmp; i >= 0; i++) {
inv.pInv[inp - 1]--;
}
return inv.pInv[inp - 1];
}
if (inp == -1) {
return true;
}
if (inp > numItems) {
cout << "Enter valid number." << endl;
return false;
}
else return false;
}
}
if (exit == true) {
return true;
}
}
So i limited the code down into a do while loop with a counter for the gold, in the buyItems() function.
Here it is, if anyone is interested.
do {
inv.gold -= inv.itemPrice[inp - 1];
++(inv.pInv[inp - 1]);
} while (inv.gold > 0);
if (inv.gold < 0) {
inv.gold = 0;
inv.pInv[inp - 1]--;
}
printItems();

Compare Class Object using bubble sort

Task: Model in OOP a class named Student containing name, surname and the marks from the winter session exams. Display the name of the students who have arrears exams and the first three students in the group.
I have troubles in comparing the marks(first three students).
My code:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include <string>
#include<stdio.h>
class Student {
private:
char nume[10];
char prenume[20];
double matematica;
double fizica;
double programare;
public:
Student(char num[10], char pren[20], double mate, double fiz, double progra);
void afis();
void citire_stud();
int restanta();
double media();
};
Student::Student(char num[10] = "", char pren[20] = "", double mate = 0, double fiz = 0, double progra = 0)
{
strcpy(nume, num);
strcpy(prenume, pren);
matematica = mate;
fizica = fiz;
programare = progra;
}
void Student::afis()
{
cout << "Nume: " << nume << endl;
cout << "Prenume: " << prenume << endl;
cout << "Nota la matematica: " << matematica << endl;
cout << "Nota fizica: " << fizica << endl;
cout << "Nota programare: " << programare << endl;
cout << endl;
}
void Student::citire_stud()
{
char num[10];
char pren[20];
double mate, fiz, progra;
cout << "Introduceti numele studentului: " << endl;
cin >> num;
strcpy(nume, num);
cout << "Introduceti preumele studentului: " << endl;
cin >> pren;
strcpy(prenume, pren);
cout << "Introduceti nota la mate studentului: " << endl;
cin >> mate;
matematica = mate;
cout << "Introduceti nota la fizica studentului: " << endl;
cin >> fiz;
fizica = fiz;
cout << "Introduceti nota la programare studentului: " << endl;
cin >> progra;
programare = progra;
}
int Student::restanta() //arrears
{
if (matematica < 5 || programare <5 || fizica < 5)
return 1;
else return 0;
}
double Student::media()
{
double med;
med = (matematica + fizica + programare) / 3;
return med;
}
void main()
{
int cont = 0;
int res[10];
int nr;
cout << "Cati studenti sunt(max 10): "; //How many students
cin >> nr;
Student ob2[10], temp;
for (int i = 0;i < nr;i++)
{
ob2[i].citire_stud();
if (ob2[i].restanta())
{
res[cont++] = i;
}
}
if (cont == 0)
{
cout << "Nu sunt studenti restanti! " << endl;
goto jmp;
}
else
{
cout << "\nStundetii restanti sunt: " << endl;
int i = 0;
int k = 0;
do
{
k = res[i];
ob2[k].afis();
i++;
} while (i != cont);
}
jmp:
cout << "\n\n\n\nStudentii in ordinea medilor sunt: " << endl;
for (int i = 0;i < nr;i++)
{
if (ob2[i].media() < ob2[i + 1].media()) //Not working
{
temp = ob2[i];
ob2[i] = ob2[i + 1];
ob2[i + 1] = temp;
}
}
for (int i = 0;i < nr;i++)
ob2[i].afis();
system("pause");
}
Output: Output
It should be: 9 - 7 - 5
Your bubble sort is broken. A) You need 2 loops. B) you go out of bounds. Change it to something like:
for (int j = 0; j < nr; j++)
{
for (int i = 0;i < nr - 1 ; i++)
{
if (ob2[i].media() < ob2[i + 1].media())
{
temp = ob2[i];
ob2[i] = ob2[i + 1];
ob2[i + 1] = temp;
}
}
}