无法从C ++中的链接列表中的对象检索值

时间:2011-10-15 19:54:35

标签: c++ linked-list

更新:添加了LinkedList.h和SymbolTable.h

所以我在学校的编程工作中遇到了困难。这是我的第一门C ++课程,之前的课程是用Java教授的。

我创建了一个SymbolTable对象的链接列表,我需要在遍历列表时从每个对象中检索id(std :: string)和value(int),但我尝试获取的任何值都返回null。

我想我在这里缺少一些基本的东西,但不确定是什么。

这是我得到的输出,注意空白行来自调用     cout<< temp-> data-> getID()<< ENDL;

我真的不知道如何修复/解决这个问题。

输出:

C:\Users\spud\Documents\Visual Studio 2010\Projects\EECS1580_assign_01\Debug>EEC
S1580_assign_01.exe
Reading file...
Parsing...id_1 = 40
id_1
40

Parsing...var_2 = 50
var_2
50

Parsing...id_1 += 30
Parsing...var_2-=20
Parsing...id_1*=5
Parsing...k_27=80
k_27
80

Parsing...k_27 /= 20
done reading..
done

这是代码

LinkedList.cpp

#include "StdAfx.h"
#include "LinkedList.h"
#include <iostream> 
#include <string>
#include "SymbolTable.h"

using namespace std;


// define node for LinkedList
typedef struct node 
{ 
    public:
        SymbolTable *data;       // data in node 
        node *next;             // link to next node 
        node() 
        {
            next = NULL;
            data = new SymbolTable();
        }
}; 


node *head = NULL;               // empty linkedList
node *tail = NULL;
node *curr = NULL;


LinkedList::LinkedList() 
{
    head = new node();           
} 

LinkedList::~LinkedList() 
{ 
   node *q; 
   if( head == NULL ) 
        return; 

   while( head != NULL ) 
   { 
        q = head->next; 
      delete head; 
      head = q; 
   }                     
} 


// insert node at front of LinkedList
void LinkedList::insert(string id, int value) 

{ 
    SymbolTable *s = new SymbolTable(id, value);

    node *temp;                   //create a temporary node 
    temp = new node;              //allocate space for node 

    temp->data = s;               // store data(first field)
    temp->next = head;            // store the address of the pointer head(second field)
    head = temp;                  // transfer the address of 'temp' to 'head'
    cout << temp->data->getID() << endl;
} 

void LinkedList::display() 
{ 
     node *q; 
     cout << endl; 

     for(q = head; q != NULL; q = q->next) 
           cout << q->data->toString() << endl;
} 


void LinkedList::traverse() 
{ 

    node *curr;
    curr = head;
    SymbolTable *temp;

    if(head == NULL)
    cout << "End of list.\n";
    else    
    {
        while(curr != NULL) {
        //cout << temp->data.toString() << " ";
            temp->setID(curr->data->getID());
            temp->setValue(curr->data->getValue());
            cout << temp->getID() << endl;
            curr = curr->next;
        }
    }
} 

/*void find(string tofind, char op, int value)
{
     node *temp1;                               // create tmp node 
     temp1 = head;                              // transfer address of p to temp1 
     //string t = "";
     while(temp1 != NULL) 
     { 
        // t = temp1->data.getID();
        // if(tofind.compare(t) == 0)
         {
             cout << "match!" << endl;
        //   temp1->data.performOp(op, value);  // perform op
         }
        // temp1 = temp1->next;                   // transfer address of temp->next to temp             
     }     
     cout << "no match!" << endl;
}*/

void LinkedList::sort() 
{ 
    node *temp, *temp1, *temp2;
    //temp = new node;
    //temp1 = new node;
    //temp2 = new node;

    for(temp1 = head; temp1 != NULL; temp1 = temp1->next)
    for(temp2 = head; temp2 != NULL; temp2 = temp2->next)
    {
        if(temp1->data->toString() < temp2->data->toString())
        {
            temp->data = temp2->data;
            temp2->data = temp1->data;
            temp1->data = temp->data;
        }
    }
} 

SymbolTable.cpp

#include "StdAfx.h"
#include "SymbolTable.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib> 

using namespace std;

    string id;
    int value;
    int final;


    void SymbolTable::setID(string s)
    {
        id = s;
    }

    void SymbolTable::setValue(int a) 
    {
        value = a;
    }

    // Will perform the requested operation on the node
    int SymbolTable::performOp(char op, int val)
{
    // final value to return
    int final = 0;
    // determine which op to use, then exec it
        switch (op) {
            case '+':
                value += val; break;
            case '-':
                value -= val; break;
            case '*':
                value *= val; break;
            case '/':
                value /= val; break;
            case '%':
                value %= val; break;
            default:
                // no operation performed
                cout << "noOp" << endl;
                break;
        }

        cout << id << " New Value: " << value << endl;

        // return the new value
        return value;
}

    // returns a string with info about the node
    string SymbolTable::toString(void)
    {
        // create new string to return
        string mString;
        // append id and = to the string
        mString.append(id).append("=");
        // append in to string
        ostringstream oss;
        oss << value;
        mString += oss.str();
        cout << mString << endl;
        // return the final string
        return mString;
    }

    // return Id 
    const string SymbolTable::getID(void)
    {
        return id;
    }
    const int SymbolTable::getValue(void)
    {
        return value;
    }

    // return the link that this obj points to
    //SymbolTable* SymbolTable::getLink()
    //{
    //  return link;
    //}

    // set link
    //void SymbolTable::setLink(SymbolTable *s)
    //{
    //  link = s;
    //}

    // Constructor
    SymbolTable::SymbolTable(string a, int v)
    {

        // initialize the id
        id = a;
        cout << getID() << endl;
        // initialize the value
        value = v;
        cout << getValue() << endl;
        final = 0;
    }
    SymbolTable::SymbolTable()
    {
        id = "";
        value = 0;
    }

    // deConstructor
    SymbolTable::~SymbolTable(void)
    {
        // clear the string
        id.clear();
        // set value to 0
        value=0;
    }

主要

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream> 
#include <algorithm>
#include "SymbolTable.h"
#include "LinkedList.h"

using namespace std;

//SymbolTable *root = NULL;

LinkedList mylist;

void parse(string line) 
{ 
     int value;
     string svalue;
     string id;
     char op;

     cout << "Parsing..." << line << endl;

     // remove all spaces                                             
     for(int i=0; i<line.length(); i++)
         if(line[i] == ' ')
             line.erase(i,1);

     int eqSpot = line.find('=');                             // find the = 
     svalue = line.substr(eqSpot+1, line.length()-1);         // set value 
     switch(line.at(eqSpot-1)){                               // set op 
                      case '+':  op = '+';  eqSpot--; break; 
                      case '-':  op = '-';  eqSpot--; break; 
                      case '*':  op = '*';  eqSpot--; break; 
                      case '/':  op = '/';  eqSpot--; break;
                      default:   op = '=';  break;          
     };

     id = line.substr(0, eqSpot);                           // set id

     stringstream ss(svalue);                               // convert std::string svalue to int value
     ss >> value;

     if(op == '=')                                          // if decleration.. 
     { 
         // create new node in the LinkedList      
                mylist.insert(id, value);                           // insert s into LL
     } 
     else                                                   // else is operation 
     { 
               // myList.find(id, op, value);
     }
} 

/*// sorts the nodes in the LL
void sort()
{
    SymbolTable *temp1;
    SymbolTable *temp2;
    SymbolTable *temp;

    cout << "Sorting Nodes..." << endl;
    for( temp1 = root ; temp1!=NULL ; temp1 = temp1->getLink() )
    {
          for( temp2 = temp1->getLink() ; temp2!=NULL ; temp2 = temp2->getLink() )
          {
                if( temp1->getID() > temp2->getID() )
                {
                      temp = temp1->getLink();
                      temp1->setLink(temp2->getLink());
                      temp2->setLink(temp);
                }
          }
    }
}
// should print out the toString for each node
void printNodes()
{
    SymbolTable *node = root;

    do
    {
        cout << node->toString() << endl;
    }while((node = node->getLink()) != NULL);
}
// Will traverse the string, comparing IDs and will return a pointer to that node or null if not found
SymbolTable* traverse(string id)
{
     SymbolTable *temp1;                          // create tmp node 
     temp1 = root;

     while(temp1 != NULL) 
     {  
        cout << temp1->toString() << endl;
        if(id.compare(temp1->getID()) == 0)
        {
            // Found!
            cout << "MATCH" << endl;
            return temp1;
        };
        cout << root->getLink() << endl;
        if(temp1 == temp1->getLink())
            temp1 = NULL;
        else
            temp1 = temp1->getLink();                // transfer address of temp->next to temp 
     };

     cout << "NO MATCH FOUND" << endl;
     return NULL;

}
*/

// some test values
int _tmain(int argc, _TCHAR* argv[])
{
    // Read input
    mylist = LinkedList();
    string line;
    ifstream myfile ("input.txt");              // input file
    if (myfile.is_open())
    {
        cout << "Reading file..." << endl;
        while ( myfile.good() )                 // read file line by line
        {
            getline(myfile,line);
            if(line.compare("</end/>") == 0)    // end of file
                break;
            else
                parse(line);                    // parse the line
        }
        myfile.close();
        cout << "done reading.." << endl;
    }
    else cout << "Unable to open file"; 

    //myList.sort();

    //myList.traverse();

    cout << "done";
    //return 0;

    return EXIT_SUCCESS; 
} 

LinkedList.h

#pragma once
#include "SymbolTable.h"
#include <string>

class LinkedList
{
private: 

public:
    LinkedList(void);
    ~LinkedList(void);
    void insert(std::string id, int value); 
    void display(); 
    void traverse();
    void sort();
    //void find(std::string, char, int);
};

SymbolTable.h

#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib> 

class SymbolTable
{
public:
    int performOp(char, int);
    std::string toString(void);
    const std::string getID(void);
    void setValue(int);
    void setID(std::string);
    const int getValue();
    SymbolTable(std::string, int);
    SymbolTable();
    ~SymbolTable(void);
};

1 个答案:

答案 0 :(得分:3)

一个问题是删除解析函数中的空格

 // remove all spaces                                             
 for(int i=0; i<line.length(); i++)
     if(line[i] == ' ')
         line.erase(i,1);

删除空格时,索引不应递增,以便您可以删除可能的下一个空格。

但是你的主要问题是拥有应该是SymbolTable成员的全局变量:

string id;
int value;
int final;

而不是上面的内容,你应该有以下内容(在SymbolTable.h中):

class SymbolTable
{
    string id;
    int value;
    int final;

    // declaration of all the member functions
    ...
};

此外,在此代码中,您不需要析构函数(您调用deConstructor的析构函数)。当对象被删除时,将自动删除所有成员。您只需要担心删除只有指针的对象。

LinkedList相关的全局变量也应该是该类的成员,而不是全局变量:

class LinkedList
{
    node *head;
    node *tail;
    node *curr;

    // declaration of all the member functions
    ...
};

他们的初始化应该在构造函数中完成:

LinkedList::LinkedList()
{
    head = NULL;               // empty linkedList
    tail = NULL;
    curr = NULL;
}