Question

I keep getting the same error messages every time on Visual Studio. I don't know where the error is originating. Basically I'm trying to convert an infix expression (A+B-C) to a postfix expression (AB+C-) using stacks. Any help would be greatly appreciated

DriverExpression.cpp

Expression.obj : error LNK2019: unresolved external symbol "public: __thiscall stackType::stackType(int)" (??0?$stackType@D@@QAE@H@Z) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

Expression.obj : error LNK2019: unresolved external symbol "public: __thiscall stackType::~stackType(void)" (??1?$stackType@D@@QAE@XZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

Expression.obj : error LNK2019: unresolved external symbol "public: char __thiscall stackType::top(void)const " (?top@?$stackType@D@@QBEDXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

Expression.obj : error LNK2019: unresolved external symbol "public: void __thiscall stackType::initializeStack(void)" (?initializeStack@?$stackType@D@@QAEXXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

Expression.obj : error LNK2019: unresolved external symbol "public: bool __thiscall stackType::empty(void)const " (?empty@?$stackType@D@@QBE_NXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

Expression.obj : error LNK2019: unresolved external symbol "public: void __thiscall stackType::push(char)" (?push@?$stackType@D@@QAEXD@Z) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

Expression.obj : error LNK2019: unresolved external symbol "public: void __thiscall stackType::pop(void)" (?pop@?$stackType@D@@QAEXXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

C:\Users\Jake Bock\Desktop\CSC 240\Project 7\JBock_Project7\Debug\JBock_Project7.exe : fatal error LNK1120: 7 unresolved externals**

#include <iostream>
#include <fstream>
#include <string>
#include <stack>
#include "Expression.h"
#include "stackType.h"

using namespace std;

int main()
{

    string fileName;
    string infixExpression, postfixExpression;
    Expression expression;
    cout << "Converting infix expression to postfix expression\n"
         << "testing infix expressions are in input file\n";
    cout << "Enter the input file name ";
    cin  >> fileName;
    ifstream inData;
    ofstream outData;
    inData.open(fileName.c_str());
    outData.open("out.txt");
    cout<<"open="<<fileName<<endl;   //debugging print
    while(inData>>infixExpression)
    {
        cout<<"Infix="<<infixExpression<<endl; //debugging print
        expression.setInfix(infixExpression);
        cout<<"setInfix="<<infixExpression<<endl;//debugging print
        expression.convertInfixToPostfix();
        cout<<"convert="<<infixExpression<<endl; //debugging print
        postfixExpression = expression.getPostfix();
        cout    << "Infix Expression: "
                << infixExpression <<"\n"
                << "Postfix Expression: "
                <<postfixExpression<<"\n\n";
        outData << "Infix Expression: "
                << infixExpression <<"\n"
                << "Postfix Expression: "
                <<postfixExpression<<"\n\n";
    }

    inData.close();
    outData.close();

    system("pause");
    return 0;
}

================================================================

    #ifndef EXPRESSION_H_
#define EXPRESSION_H_
#include "stackType.h"

class Expression
{
private:
    std::string infixExpression;
    std::string postfixExpression;

    bool precedence(char s, char operator2); //ToDo
    bool isOperand(char symbol);                     //ToDo

public:

    Expression();
    void setInfix(std::string infix);
    std::string getInfix();
    std::string getPostfix();
    void convertInfixToPostfix();        //ToDo
    static void convertInfixToPostfix(   //ToDo
                std::string& infix,
                std::string& postfix);
    virtual ~Expression();
};

#endif /* EXPRESSION_H_ */

#include <stack>
#include <string>
#include <sstream>
#include "Expression.h"
#include "stackType.h"
#include <iostream>
using namespace std;


Expression::Expression() : infixExpression(""), postfixExpression(""){}


void Expression::setInfix(string infix)
{
    infixExpression= infix;
}


string Expression::getInfix()
{
    return infixExpression;
}


string Expression::getPostfix()
{
    return postfixExpression;
}


void Expression::convertInfixToPostfix()
{
    /*Define operator stack*/
    stackType<char> s(infixExpression.size());
    s.initializeStack();
    ostringstream strstream;

    int operand = 0;
    /*String stream will help us pushing integer to our stream easily.
    This is similar to sprintf(), but with less hassles.*/
    int size = infixExpression.size();
    int iter = 0;
    for (; iter < size; ++iter)
    {
        switch (infixExpression[iter])
        {
        case '+':
        case '-':
        case '/':
        case '*':
            {
                if (s.empty())
                {
                    /*We always push the first operator*/
                    s.push(infixExpression[iter]);
                }
                else
                {
                    /*if precedence of current operator is higher than
                    one on top of the stack, we simply push the current
                    operator to the top of the stack*/
                    if (precedence(s.top(), infixExpression[iter]))
                    {
                        s.push(infixExpression[iter]);
                    }
                    else
                    {
                        /*Pop from the stack and append it to string stream.
                        Repeat it unless we find an operator on top of the stack
                        whose precedence is lower or stack is empty.*/
                        do
                        {
                            strstream << s.top() << ' ';
                            s.pop();
                        }while (!s.empty() && !precedence(s.top(), infixExpression[iter]));
                        /*Now push the current operator to the stack*/
                        s.push(infixExpression[iter]);
                    }
                }
                break;
            }
        case ' ':
            {
                break;
            }
        default:
            {

                while (iter < size && infixExpression[iter] >= '0' && infixExpression[iter] <= '9')
                {
                    operand = operand * 10 + (infixExpression[iter]-'0');
                    ++iter;
                }
                strstream << operand << ' ';
                operand = 0;
                --iter;
                break;
            }
        }
    }
    /*Pop one by one from operator stack and append it to our stream*/
    while(!s.empty())
    {
        strstream << s.top() << ' ';
        s.pop();
    }
    /*Get the string associated with our string stream*/
    postfixExpression = strstream.str();
}


bool Expression::precedence(char s, char operator_specified)
{

    if ((operator_specified == '+') || (operator_specified == '-'))
        return false;
    char top_operator = s;
    if ((top_operator == '+') || (top_operator == '-'))
        return true;
    else
        return false;
}

Expression::~Expression()
{
}

//=======================================================================================

 #ifndef STACKTYPE_H_
#define STACKTYPE_H_


template <class T>
class stackType
{
private:

    int maxStackSize;
    int stackTop;
    char *list;

    void copyStack(const stackType& otherStack);

public:

    stackType();
    stackType(int stackSize);
    ~stackType();
    char top() const;
    void initializeStack();
    bool empty() const;
    void push(const char newItem);
    bool isFullStack() const;
    void pop();
    const stackType& operator=(const stackType& otherStack);
};

#endif /* stackType_H_ */

#include "stackType.h"
#include <stack>
#include <cassert>

template <class T>
stackType<T>::stackType(){}

template <class T>
stackType<T>::stackType(int stackSize)
{
    if (stackSize <= 0)
    {
        cout << "Size of the array to hold the stack must be positive" << endl;
        cout << "Creating an array of size 100" << endl;

        maxStackSize = 100;
    }
    else
        maxStackSize = stackSize;

    stackTop = 0;
    list = new char[maxStackSize];
}

template <class T>
stackType<T>::~stackType()
{
    delete [] list;
}

template <class T>
char stackType<T>::top() const
{
    assert(stackTop != 0);
    return list[stackTop - 1];
}

template <class T>
void stackType<T>::initializeStack()
{
    stackTop = 0;
}

template <class T>
bool stackType<T>::empty() const
{   
    return (stackTop == 0);
}

template <class T>
bool stackType<T>::isFullStack() const
{
    return (stackTop == maxStackSize);
}

template <class T>
void stackType<T>::pop()
{
    if (!isEmptyStack())
        stackTop--;
    else
        cout << "Cannot remove from an empty stack" << endl;
}

template <class T>
void stackType<T>::push(const char newItem)
{
    if (!isFullStack())
    {
        list[stackTop] = newItem;
        stackTop++;
    }
    else
        cout << "Cannot add to a full stack" << endl;
}

template <class T>
void stackType<T>::copyStack(const stackType& otherStack)
{
    delete [] list;
    maxStackSize = otherStack.maxStackSize;
    stackTop = otherStack.stackTop;
}


template <class T>
const stackType<T>& stackType<T>::operator=(const stackType& otherStack)
{
    if (this != &otherStack)
        copyStack(otherStack);
    return *this;
}
Was it helpful?

Solution

unresolved external symbol

Okay, so you've got a linker error here. Whenever you get that, here's the process for fixing it. First, let's look at the error message.

public: __thiscall stackType::stackType(int)" (??0?$stackType@D@@QAE@H@Z) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix@Expression@@QAEXXZ)

  1. Figure out what method isn't linking. Looking at the error message, it's clearly stackType::stackType(int).

Now what's happening is your method (in this case, a constructor) is declared but never defined. So, go through the checklist...

  1. Is stackType.cpp being included into your build?

  2. Did you remember to write stackType::stackType(int) in your .cpp file?

  3. Are the method signatures for the two functions the same? Did you make one a const method and the other not?

  4. Any weird spelling errors in the class or method name?

  5. Are you doing anything wrong involving templates?

My guess is that #4 is the culprit here, since stackType is a template class. You need to stick all those method definitions into the header and probably aren't.

OTHER TIPS

So the problem turned out being that I needed to keep the template class member function definitions in the header file only. Oy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top