Error: Not found in scope

I'm attempting to write a program that will allow me to buy and sell items using LIFO and FIFO depending on the user input. Buying works well enough (though the compiler says there is an invalid conversion from Widget* to int), but it refuses to recognize any of the declared objects in the Sell function.

.h file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#if !defined (INVENTORYMANAGER_H)
#define INVENTORYMANAGER_H

#include "StackDeque.h"
#include "QueueDeque.h"
#include "Widget.h"
#include <iostream>
#include <iomanip>
using namespace std;

class InventoryManager
{
	private:
		int inv_choice;
		int buy;
		int sell;
		double profit;
		StackDeque<Widget>* stack;
		QueueDeque<Widget>* queue;
	public:
		InventoryManager(int inventory_choice);	//LIFO	or	FIFO
		~InventoryManager();
		void buyWidgets(double cost, int num_to_buy);
		double getTotalProfit();
		double sellWidgets(double price, int num_to_sell);
};

InventoryManager::InventoryManager(int inventory_choice)
{
	inv_choice = inventory_choice;
	buy = 0;
	sell = 0;
	profit = (sell - buy);
	
	stack = new StackDeque<Widget>();
	queue = new QueueDeque<Widget>();
}

InventoryManager::~InventoryManager()
{
	delete stack;
	delete queue;
}

void InventoryManager::buyWidgets(double cost, int num_to_buy)
{	
	if(inv_choice == 1)
	{
		for(int i = 0; i < num_to_buy; i++)
		{
			stack->push(num_to_buy);
			buy = (cost * num_to_buy);
		}
	}
	else if(inv_choice == 2)
	{
		for(int i = 0; i < num_to_buy; i++)
		{
			queue->enqueueDeque(num_to_buy);
			buy = (cost * num_to_buy);
		}
	}
}

double getTotalProfit()
{
	return profit;
}

double sellWidgets(double price, int num_to_sell)
{	
	if(inv_choice == 1)
	{
		for(int i = 0; i < num_to_sell; i++)
		{
			stack->pop();
			sell = (price * num_to_sell);
		}
	}
	else if(inv_choice == 2)
	{
		for(int i = 0; i < num_to_sell; i++)
		{
			queue->dequeueDeque();
			sell = (price * num_to_sell);
		}
	}
	
	cout << getTotalProfit();
	
	return sell;
}

#endif 


.cpp file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "InventoryManager.h"

#include <iostream>
#include <iomanip>

int main()
{
	int num = 1;
	Widget* widget = new Widget(10);
	InventoryManager* deque = new InventoryManager(1);
	
	deque->buyWidgets(widget, num);
	
	delete widget;
	delete deque;
	
	return 0;
}


Error message:


In file included from InventoryManager.cpp:1:0:
InventoryManager.h: In member function 'void InventoryManager::buyWidgets(double, int)':
InventoryManager.h:51:26: error: invalid conversion from 'int' to 'Widget*' [-fpermissive]
    stack->push(num_to_buy);
                          ^
In file included from InventoryManager.h:4:0,
                 from InventoryManager.cpp:1:
StackDeque.h:71:6: error:   initializing argument 1 of 'void StackDeque<T>::push(T*) [with T = Widget]' [-fpermissive]
 void StackDeque<T>::push(T* item)
      ^
In file included from InventoryManager.cpp:1:0:
InventoryManager.h:59:34: error: invalid conversion from 'int' to 'Widget*' [-fpermissive]
    queue->enqueueDeque(num_to_buy);
                                  ^
In file included from InventoryManager.h:5:0,
                 from InventoryManager.cpp:1:
QueueDeque.h:94:6: error:   initializing argument 1 of 'void QueueDeque<T>::enqueueDeque(T*) [with T = Widget]' [-fpermissive]
 void QueueDeque<T>::enqueueDeque(T* item)
      ^
In file included from InventoryManager.cpp:1:0:
InventoryManager.h: In function 'double getTotalProfit()':
InventoryManager.h:67:9: error: 'profit' was not declared in this scope
  return profit;
         ^
InventoryManager.h: In function 'double sellWidgets(double, int)':
InventoryManager.h:72:5: error: 'inv_choice' was not declared in this scope
  if(inv_choice == 1)
     ^
InventoryManager.h:76:4: error: 'stack' was not declared in this scope
    stack->pop();
    ^
InventoryManager.h:77:4: error: 'sell' was not declared in this scope
    sell = (price * num_to_sell);
    ^
InventoryManager.h:84:4: error: 'queue' was not declared in this scope
    queue->dequeueDeque();
    ^
InventoryManager.h:85:4: error: 'sell' was not declared in this scope
    sell = (price * num_to_sell);
    ^
InventoryManager.h:91:9: error: 'sell' was not declared in this scope
  return sell;
         ^


Thanks for any help.
Last edited on
Line 51: stack is a stack of Widgets (line 18). You can't push an int when a Widget is expected.

Line 59: Ditto for queue.

Line 65: getTotalProfit is not qualified by the class name.

Line 70: Ditto for sellWidgets.


BTW, you should NOT include your function implementations in your .h file. They belong in a .cpp file. Doing so will cause linker errors, should you include inventorymanager.h in more than one place.

Last edited on
That fixed it. Thanks for that. However, now I have an undefined reference to error, and I'm not sure why, as I believe my build file is correct.

New .cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "InventoryManager.h"

#include <iostream>
#include <iomanip>

int main()
{
	Widget* num = new Widget(1);
	Widget* widget = new Widget(10);
	InventoryManager* deque = new InventoryManager(1);
	
	double wid = widget->getCost();
	int number = num->getCost();
	
	deque->buyWidgets(wid, number);
	
	delete num;
	delete widget;
	delete deque;
	
	return 0;
}

InventoryManager::InventoryManager(int inventory_choice)
{
	inv_choice = inventory_choice;
	buy = 0;
	sell = 0;
	profit = (sell - buy);
	
	stack = new StackDeque<Widget>();
	queue = new QueueDeque<Widget>();
}

InventoryManager::~InventoryManager()
{
	delete stack;
	delete queue;
}

void InventoryManager::buyWidgets(double cost, int num_to_buy)
{
	Widget* num = new Widget(1);
	int number = num->getCost();
	
	if(inv_choice == 1)
	{
		for(int i = 0; i < number; i++)
		{
			stack->push(num);
			buy = (cost * number);
		}
	}
	else if(inv_choice == 2)
	{
		for(int i = 0; i < number; i++)
		{
			queue->enqueueDeque(num);
			buy = (cost * number);
		}
	}
	
	delete num;
}

double InventoryManager::getTotalProfit()
{
	return profit;
}

double InventoryManager::sellWidgets(double price, int num_to_sell)
{
	Widget* num = new Widget(1);
	int number = num->getCost();
	
	if(inv_choice == 1)
	{
		for(int i = 0; i < number; i++)
		{
			stack->pop();
			sell = (price * number);
		}
	}
	else if(inv_choice == 2)
	{
		for(int i = 0; i < number; i++)
		{
			queue->dequeueDeque();
			sell = (price * number);
		}
	}
	
	cout << getTotalProfit();
	
	return sell;
	
	delete num;
}


Build file:

1
2
3
4
5
6
7
8
9
10
11
@echo off
cls


::set DRIVE_LETTER=%1:
::set PATH=%DRIVE_LETTER%\MinGW\bin;%DRIVE_LETTER%\MinGW\msys\1.0\bin;c:\Windows;c:\Windows\system32

g++ -I.\CSC2110 -c InventoryManager.cpp

g++ -L.\CSC2110 -o  InventoryManager.exe InventoryManager.o Widget.o -lCSC2110
InventoryManager.exe


Error message:


InventoryManager.o:InventoryManager.cpp:(.text+0x2e): undefined reference to `Widget::Widget(double)'
InventoryManager.o:InventoryManager.cpp:(.text+0x52): undefined reference to `Widget::Widget(double)'
InventoryManager.o:InventoryManager.cpp:(.text+0x273): undefined reference to `Widget::Widget(double)'
InventoryManager.o:InventoryManager.cpp:(.text+0x3c9): undefined reference to `Widget::Widget(double)'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: InventoryManager.o: bad reloc address 0x2c in section `.text$_ZN10StackDequeI6WidgetEC1Ev[__ZN10StackDequeI6WidgetEC1Ev]'
collect2.exe: error: ld returned 1 exit status
'InventoryManager.exe' is not recognized as an internal or external command,
operable program or batch file.
You didn't post your current .h file, so I have to assume you're using the same class declaration as before.

Line 24: Implements a constructor that takes an int.
The linker errors say that the linker is expecting a constructor that takes a double. I see no constructor implemented in your new main that takes a double.


Last edited on
Thanks for your help. I have one last question. After successfully testing it in IM.cpp, I tried moving it to InventoryDriver.cpp to finish the program. However, it says that I have multiple definitions of main. I checked my includes, and I don't have any .cpp files, and I deleted the main() that was in my IM.cpp, so I'm not sure what the problem could be.

ID.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "InventoryManager.h"
#include "Text.h"
using CSC2110::String;
#include "Keyboard.h"
using CSC2110::Keyboard;

#include <iostream>
#include <iomanip>
using namespace std;

int inventoryChoice()
{
   Keyboard* kb = Keyboard::getKeyboard();
   int inv_choice = kb->getValidatedInt("Are you using (1) LIFO or (2) FIFO inventory management? ", 1, 2);
   return inv_choice;
}

//DO THIS
//buy Widgets (check invalid input and reprompt if necessary)
void buyWidgets(InventoryManager* im)
{
	int user;
	double user2;
	int inventory_choice;
	InventoryManager* deque = new InventoryManager(inventory_choice);
	
	cout << "Input the price and number of widgets you wish to buy:\n" << "Price: ";
	cin >> user2;
	cout << "Number: ";
	cin >> user;
	
	Widget* num = new Widget(user);
	Widget* widget = new Widget(user2);
	
	int number = num->getCost();
	double wid = widget->getCost();
	
	deque->buyWidgets(wid, number);
	
	delete deque;
	delete num;
	delete widget;
}

//DO THIS
//sell Widgets and return the profit (check invalid input and reprompt if necessary)
double sellWidgets(InventoryManager* im)
{
	int user;
	double user2;
	int inventory_choice;
	InventoryManager* deque = new InventoryManager(inventory_choice);
	double sell;
	
	cout << "Input the price and number of widgets you wish to sell:\n" << "Price: ";
	cin >> user2;
	cout << "Number: ";
	cin >> user;
	
	Widget* num = new Widget(user);
	Widget* widget = new Widget(user2);
	
	int number = num->getCost();
	double wid = widget->getCost();
	
	deque->sellWidgets(wid, number);
	
	return sell;
	
	delete deque;
	delete num;
	delete widget;
}

bool mainMenu(InventoryManager* im)
{
   Keyboard* kb = Keyboard::getKeyboard();
   int menu_choice = kb->getValidatedInt("1. Buy Widgets \r\n2. Sell Widgets\r\n3. Quit\r\nWhat would you like to do? ", 1, 3);

   double profit = 0;

   if (menu_choice == 1)
   {
      buyWidgets(im);
      return 1;
   }
   else if(menu_choice == 2)
   {
      sellWidgets(im);
      return 1;
   }
   else 
   {
      return 0;
   }
}

int main()
{
   cout << setprecision(2) << fixed;

   int inv_choice = inventoryChoice();
   InventoryManager* im = new InventoryManager(inv_choice);

   bool ask = 1;
   while (ask)
   {
      ask = mainMenu(im);
   }

   double running_total = im->getTotalProfit();
   cout << "Your total profit for all transactions is $" << running_total << endl;

   delete im;
}


Build.bat:

1
2
3
4
5
6
7
8
9
10
11
@echo off
cls


::set DRIVE_LETTER=%1:
::set PATH=%DRIVE_LETTER%\MinGW\bin;%DRIVE_LETTER%\MinGW\msys\1.0\bin;c:\Windows;c:\Windows\system32

g++ -I.\CSC2110 -c InventoryDriver.cpp

g++ -L.\CSC2110 -o  InventoryDriver.exe InventoryDriver.o InventoryManager.o Widget.o -lCSC2110
InventoryManager.exe


Error:


InventoryManager.o:InventoryManager.cpp:(.text+0x0): multiple definition of `main'
InventoryDriver.o:InventoryDriver.cpp:(.text+0x468): first defined here
collect2.exe: error: ld returned 1 exit status


IM.cpp is the same as it was before, just without the main function.
Last edited on
build.bat line 8: I only see a compile rule for InventoryDriver.cpp:

I don't see anything that would cause you to compile IM.cpp.

At line 10, you're linking InventoryManager.o, which has not been compiled, so I'm assuming you're getting an old version of the object file.




Sorry to keep bothering you with this, but I have one final problem, and it involves the main point of my program. It runs fine, but it refuses to keep the total profit. No matter what I input, it always outputs $0.00 as the total profit.
Sorry to keep bothering you with this

No need to apologize for asking reasonable questions.

it refuses to keep the total profit

Line 46 says that sellWidgets() returns the profit. There are several problems with that assumption.

Line 53: sell is an uninitialized variable.

Line 68: You never set the value of sell and return an uninitialized variable.

Lines 70-72: These lines will never execute.

Line 89: You ignore the return value from sellWidgets().
Last edited on
Alright, I've made some major changes to my buy and sell functions, including deleting junk data, and using another file that my professor prefers we use as opposed to cin and cout statements. But it still continues to output nothing but 0.00, no matter what I try.

New sell function in .cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//DO THIS
//sell Widgets and return the profit (check invalid input and reprompt if necessary)
double sellWidgets(InventoryManager* im)
{
	Keyboard* kb = Keyboard::getKeyboard();
	int num_to_sell = kb->readInt("How many widgets would you like to sell? ");
	double price = kb->readDouble("What is the selling price for each widget? ");
	
	int inventory_choice;
	InventoryManager* deque = new InventoryManager(inventory_choice);
	double sell = 0;
	
	deque->sellWidgets(price, num_to_sell);
	
	cout << setprecision(2) << sell;
	
	delete deque;
	
	return sell;
}


Sell in .h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
double InventoryManager::sellWidgets(double price, int num_to_sell)
{	
	if(inv_choice == 1)
	{
		for(int i = 0; i < num_to_sell; i++)
		{
			stack->pop();
			sell = (price * num_to_sell);
		}
	}
	else if(inv_choice == 2)
	{
		for(int i = 0; i < num_to_sell; i++)
		{
			queue->dequeueDeque();
			sell = (price * num_to_sell);
		}
	}
	else
		return 0;

	return sell;
}


Keyboard.h function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Keyboard
{
   private:
      Keyboard();

   public:
      virtual ~Keyboard();
      static Keyboard* getKeyboard();

//pre: the string (character literal) that will prompt the user for input
//post: the input read from the keyboard interpreted as an int is returned
int readInt(string prompt);
int getValidatedInt(string prompt, int min, int max);

//pre: the string that will prompt the user for input
//post: the input read from the keyboard interpreted as a double is returned
double readDouble(string prompt);
double getValidatedDouble(string prompt, double min, double max);


Example output:


Are you using (1) LIFO or (2) FIFO inventory management? 1
1
1. Buy Widgets
2. Sell Widgets
3. Quit
What would you like to do? 1
1
How many widgets would you like to buy? 5
What is the buying price for each widget? 9.6
1. Buy Widgets
2. Sell Widgets
3. Quit
What would you like to do? 2
2
How many widgets would you like to sell? 4
What is the selling price for each widget? 15
0.001. Buy Widgets
2. Sell Widgets
3. Quit
What would you like to do? 3
3
Your total profit for all transactions is $0.00
Last edited on
sellWidgets() (in .cpp)
Line 11: You initialize sell to 0
You never change sell.
Line 19: You return sell. How can it be anything other than 0?

Topic archived. No new replies allowed.