Thread: Error C3861 causing me to tear my hair out.

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    3

    Error C3861 causing me to tear my hair out.

    Hi all,

    I'm trying to design a program that implements a binary tree structure, with special nodes that contain an integer data value, and a string indicating their position relative to the tree's root. I'm almost positive I've got this thing figured out, but I can't test it because VS2010 keeps insisting it can't understand my code. I keep getting C3861 errors. I'll post my code here. Bear in mind this will be using 5 different files.

    1. Node.h
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    #ifndef _Node_h_included_
    #define _Node_h_included_
    
    
    
    class Node
    {
        public: 
             Node(int val=-1, string pa=""){value = val; path = pa;}
             void set(int val=-1, string pa=""){value = val; path = pa;}
             int getVal() {return value;}
             string getPath() {return path;}
             void print() {cout<<value<<","<<path<<endl;}
    
        private:
            int value;
            string path;
    };
    #endif
    2. tNode.h
    Code:
    #include <iostream>
    #include "Node.h"
    #include <string>
    
    using namespace std;
    
    #ifndef _tNode_h_included_
    #define _tNode_h_included_
    
    
    struct tNode
    {
            Node node;
            tNode *left;
            tNode *right;
    
    };
    #endif
    3. SumTreeClass.h
    Code:
    #include <iostream>
    #include <string>
    #include "Node.h"
    #include "tNode.h"
    #include <vector>
    
    using namespace std;
    
    #ifndef _SumTreeClass_h
    #define _SumTreeClass_h
    
    class SumTreeClass
    {
        public:
            tNode BuildTree(vector <Node> nodes, tNode *head);
            void PrintOut(tNode *head);
            vector<Node> SortNodes(vector <Node> nodes);
            bool DataBalanced(tNode *head);
            bool TreeBalanced(tNode *head);
            bool Complete(tNode *head);
            bool Full(tNode *head);
        private:
            int sum(tNode *head);
            int height(tNode *head);
            
    };
    
    #endif
    4. SumTreeClass.cpp

    Code:
    #include "Node.h"
    #include "SumTreeClass.h"
    #include "tNode.h"
    #include <vector>
    #include <algorithm>
    #include <string>
    using namespace std;
    
    #ifndef _SumTreeClass_cpp_included_
    #define _SumTreeClass_cpp_included_
    
    
    
    
    vector<Node> SumTreeClass::SortNodes(vector<Node> nodes)
    {
        vector<Node> Sorted;
        vector<string> targetStrings;
    
        for(int i = 0;i < nodes.size();i++)
            targetStrings.push_back(nodes[i].getPath());
        sort(targetStrings.begin(), targetStrings.end());
        for(int i = 0; i < targetStrings.size(); i++)
            for(int k = 0; targetStrings[i] != nodes[k].getPath();k++)
            {
                if(nodes[k].getPath() == targetStrings[i])
                {
                    Sorted.push_back(nodes[k]);
                    nodes.erase(nodes.begin() + k);
                }
            }
        return Sorted;
    }
    
    tNode SumTreeClass::BuildTree(vector<Node> nodes, tNode *head)
    {
        if(nodes.empty() == true)
            return *head;
        else
        {
            tNode temp; 
            temp.node = nodes[0];
            temp.left = NULL;
            temp.right = NULL;
    
            string tempPath = temp.node.getPath();
            if(tempPath.empty() == true)
            {
                head = &temp;
                nodes.erase(nodes.begin());
                BuildTree(nodes, head);
            }
            else if(tempPath[0] == 'L')
            {
                if(head->left != NULL)
                    BuildTree(nodes, head -> left);
    
                else if (head->left == NULL && tempPath.size() != 1)
                {
                    temp.node.set(-1, "");
                    head-> left = &temp;
                    BuildTree(nodes, head -> left);
                }
    
                else if (head->left == NULL && tempPath.size() == 1)
                {
                    head -> left = &temp;
                    nodes.erase(nodes.begin());
                    tempPath.erase(tempPath.begin());
                    BuildTree(nodes, head);
                }
            }
    
            else if(tempPath[0] == 'R')
            {
                if(head->right != NULL)
                    BuildTree(nodes, head -> right);
    
                else if (head->right == NULL && tempPath.size() != 1)
                {
                    temp.node.set(-1, "");
                    head -> right = &temp;
                    tempPath.erase(tempPath.begin());
                    BuildTree(nodes, head -> right);
                }
    
                else if (head->right == NULL && tempPath.size() == 1)
                {
                    head -> right = &temp;
                    nodes.erase(nodes.begin());
                    tempPath.erase(tempPath.begin());
                    BuildTree(nodes, head);
                }
            }
    
        }
    
    }
    
    
    bool SumTreeClass::DataBalanced (tNode *head)
    {
        int l, r;
        l = sum(head -> left);
        r = sum(head -> right);
        if (l - r <= 1 && l - r >= -1)
            return true;
        else
            return false;
    }
    
    bool SumTreeClass::TreeBalanced (tNode *head)
    {
        int l, r;
        l = height(head -> left);
        r = height(head -> right);
        if (l - r <= 1 && l - r >= -1)
            return true;
        else
            return false;
    }
    
    bool SumTreeClass::Complete(tNode *head)
    {
        if(head == NULL)
            return false;
        else if (head -> left == NULL && head ->right != NULL)
            return false;
        else if (head -> left == NULL && head -> right == NULL)
            return true;
        else if (TreeBalanced(head) == false)
            return false;
        else
            return (Complete(head->left) && Complete(head->right));
    }
    
    bool SumTreeClass::Full(tNode *head)
    {
        if(head == NULL)
            return false;
        else if((head -> left != NULL && head ->right == NULL) || (head -> left == NULL && head ->right != NULL))
            return false;
        else if ((head -> left == NULL && head ->right == NULL))
            return true;
        else 
            return(Full(head->left) && Full(head->right));
    }
    
    void SumTreeClass::PrintOut(tNode *head)
    {
        static int h = height(head);
        if(head == NULL)
            cout << "Empty Tree!" << endl;
        else
        {
            
            for(int i = 0; i < (h - height(head)); i++)
                cout << "     ";
            cout << head -> node.getVal() << endl;
            PrintOut(head -> right);
            PrintOut(head -> left);
        }
    
        if(TreeBalanced(head) == true)
            cout << "Balanced ";
        else
            cout << "Unbalanced ";
        if(DataBalanced(head) == true)
            cout << "Data Balanced ";
        else
            cout << "Data Unbalanced ";
        if(Complete(head) == true)
            cout << "Complete ";
        else
            cout << "Incomplete ";
        if(Full(head) == true)
            cout << "Full " << endl;
        else
            cout << "Not Full " << endl;
    }
    
    int SumTreeClass::height(tNode *head)
    {
        if (head == NULL)
            return 0;
        else if (head->right == NULL && head->left == NULL)
            return 0;
        else
            return 1 + max(height(head->left), height(head->right));
    }
    
    int SumTreeClass::sum(tNode *head)
    {
        if (head == NULL)
            return 0;
        else if (head -> left == NULL && head ->right == NULL)
            return head -> node.getVal();
        else
            return sum (head -> left) + sum (head ->right);
    }
    
    #endif
    5. SumTree.cpp
    Code:
    #include "SumTreeClass.h"
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <string>
    #include "Node.h"
    #include "tNode.h"
    
    using namespace std;
    
    vector<Node> getInput();
    
    int main()
    {
         vector<Node> treeNodes;
         tNode head;
         do
          {
              treeNodes.clear();
              treeNodes = getInput();
              treeNodes = SortNodes(treeNodes);
              head = BuildTree(treeNodes, &head);
              PrintOut(*head);
          } while(treeNodes.size() > 0);
         system("pause");
         return 0;
    }
    
    vector<Node> getInput()
    {
     char line[256];
     string lineString;
     string nodeString;
     bool endOfTree = false;
     int openPos, closePos, commaPos; // positions of the delimiters
     int value;
     string path;
     Node node;
     vector<Node> nodes;
    
     while (!endOfTree)
     {
         cin.getline(line,256);
         lineString = line;
         while (!endOfTree && lineString.size() > 0)
         {
            openPos = lineString.find('(');
            closePos = lineString.find(')');
            commaPos = lineString.find(',');
            if (openPos == string::npos || commaPos == string::npos) 
                endOfTree = true;
            else
            {
              nodeString = lineString.substr(openPos+1, closePos - openPos -1);
              lineString = lineString.substr(closePos+1, lineString.size() - closePos);
              commaPos = nodeString.find(',');
              //cout<<"Node string is "<<nodeString<<endl;
              value =atoi(nodeString.substr(0,commaPos).c_str());
              path = nodeString.substr(commaPos+1,nodeString.size()-commaPos+1);
              node.set(value, path);
              nodes.push_back(node);
              //cout<<"value= "<<value<<"\t path= "<<path<<endl;
            }
         }
     }
     return nodes;
    }
    I'm getting the errors in SumTree.cpp. The errors are saying that SortNodes, BuildTree and PrintOut, identifier not found. Am I using them wrong? Or is there some kind of weird linker error? The compiler shows no other errors. Please help!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You have no class instance variable.

    Eg
    SumTreeClass foo;
    foo.BuildTree(treeNodes, &head);

    It might be worth storing a tNode INSIDE the class, rather than having to return and pass it in every subsequent call.

    Then you can do
    foo.print();
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Stop using char arrays. Use std::string. Instead of std::cin.getline, use std::getline. Works with strings.
    Stop declaring every bloody variable on the top of the function. This isn't C. Declare them where you need them, especially temp variables.
    I think you are mistreating the design, too. The list is supposed to be self-satisfiable, or whatever to call it, which basically means that it should declare and book-keep any data it needs to create and maintain a list. You seem to be passing in a vector which it uses to hold nodes. That's just wrong. And you're passing it by-value, too, which means everything is copied everytime a call is made. And no nodes are returned to the caller either.
    Learn private variables. Heck, why don't you start with something smaller to get the hang of OOP design?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User DynV's Avatar
    Join Date
    Jul 2012
    Location
    Montreal, Canada
    Posts
    20
    For SumTreeClass::BuildTree(vector<Node>, tNode *), I'd change
    Code:
    else if(tempPath[0] == 'L') { //...
    to
    Code:
    else { helperFunction(tempPath[0]); }
    I wonder... Did you just code most of this then finally decided to compile it? Or was it incremental (code, compile, code, compile, ...) ?
    Last edited by DynV; 07-13-2012 at 12:07 AM. Reason: incremental?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. error C3861
    By emmagood in forum C++ Programming
    Replies: 10
    Last Post: 05-28-2012, 04:50 AM
  2. error C3861: 'Create': identifier not found
    By mark103 in forum C++ Programming
    Replies: 1
    Last Post: 04-23-2011, 10:01 AM
  3. Error C3861: 'menu': identifier not found
    By blacknail in forum C++ Programming
    Replies: 6
    Last Post: 09-11-2009, 09:34 AM
  4. error C3861,
    By jordanguyoflove in forum C Programming
    Replies: 3
    Last Post: 11-26-2008, 07:39 AM
  5. Error messages C3861 and C2084 in user-defined headers
    By JackR in forum C++ Programming
    Replies: 2
    Last Post: 09-11-2006, 12:42 PM