更新:添加了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);
};
答案 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;
}