我的Stack中的pop函数返回奇怪的字符--C ++

时间:2015-07-19 06:20:09

标签: c++ string stack infix-notation

我的C ++中的Stack和String函数存在严重问题。 我已经编码了我的字符串并且完全正常工作但现在我不知道该怎么做。我的堆栈也是,我已经使用了我的Stack类和整数,但是当我尝试使用我的String(ADT)时没有用。

Stack.hpp:

// Stack.hpp

#ifndef CS2_STACK_CPP
#define CS2_STACK_CPP

#include <iostream>

template<class T>
class node{
public:
    T nodeValue;
    node<T> *next;
    node(): next(NULL){};
    node(const T& item):nodeValue(item){};
};

template<class T>
class Stack{
public:
    node<T> *TOS;
    Stack(): TOS(NULL){};
    Stack(const Stack<T>&);
    ~Stack();
    void push(const T&);
    T pop();
    Stack<T>& operator=(const Stack<T>&);
    void cpList(const Stack<T>& S);
};

template<class T>
Stack<T>::Stack(const Stack<T> &S){
    node<T> *curr = S.TOS, *back;
    if(curr == NULL){
        TOS = NULL;
    }else{
        curr = curr -> next;
        TOS = new node<T>(S.TOS -> nodeValue);
        back = TOS;
        while(curr != NULL){
            back -> next = new node<T>(curr -> nodeValue);
            back = back -> next;
            curr = curr -> next;
        }
    }
}

template<class T>
Stack<T>::~Stack(){
    node<T> *curr, *pnext;
    curr = TOS;
    while(curr != NULL){
        pnext = curr -> next;
        delete curr;
        curr = pnext;
    }
    delete TOS;
}

template<class T>
void Stack<T>::push(const T &item){
    node<T> *p;
    p = new node<T>(item);
    if (TOS != NULL) {
        p -> next = TOS;
        TOS = p;
    } else {
        TOS = p;
    }
}

template<class T>
T Stack<T>::pop(){
    node<T> *p;
    T item;
    if(TOS != NULL){
        item = TOS -> nodeValue;
        p = TOS;
        TOS = TOS -> next;
        return p -> nodeValue;
        delete p;
    } else {
        std::cout << "Empty stack!" << std::endl;
    }
}

template<class T>
Stack<T>& Stack<T>::operator=(const Stack<T>& S){

    if(this == &S){
        return *this;
    }

    node<T> *curr, *pnext, *nNode, *last = NULL;
    curr = TOS;
    while(curr != NULL){
        pnext = curr -> next;
        delete curr;
        curr = pnext;
    }

    cpList(S);
    return *this;
}

template <class T>
void Stack<T>::cpList(const Stack<T>& S){
    node<T> *ptr, *newNode, *last = NULL;

    ptr = S.TOS;

    while(ptr != NULL){
        newNode = new node<T>(ptr->nodeValue);
        if (last == NULL){
            TOS = newNode;
        }else{
            last->next = newNode;
        }
        last = newNode;
        ptr = ptr -> next;
    }

}

#endif

String.hpp:

// String.hpp

#ifndef CS2_STRING_H
#define CS2_STRING_H

#include <iostream>

const int SIZE = 256;

class String
{
public:
    // Constructor method without value
    String();

    // Constructor method receiving a char array
    String(const char*);

    // Constructor method receiving a char array
    String(const char);

    // Constructor method receiving a size and a char
    // Precondition: The size need to be equal or greater
    // than the size of the char
    // Postcondition: Create a String with a end character '\0'
    String(int,const char*);

    // Constructor method just receiving a size
    // Precondition: Size need to be equal or greater than 0
    // Postcondition: Generate a String with that capacity and
    // with just a end character '/0' at the position 0
    String(int);

    // Copy constructor
    String(const String&);

    // Destructor method for String class
    ~String();

    void resize(int); 

    // Return the actual capacity of the String
    int getCapacity()const;

    // Precondition: A valid String or char[]
    // Postcondition: Return and integer with the length
    int length()const;

    // Precondition: Insert a positive integer
    // Post condition: Return a char in that position
    char getChar(int)const;

    // Precondition: Insert a positive integer
    // Postcondition: Return a char in that position
    char operator[](int)const;

    // Precondition: 
    // Postcondition: 
    void swap(String&);

    // Precondition: Insert and positive value initial, less than
    // SIZE and a positive value for the end less than SIZE
    // Postcondition: Return a String inside this interval 
    // (initial to end)
    String substring(int,int)const;

    // Precondition: Insert a valid char
    // Postcondition: Return the integer with the position of the
    // char, if don't return 0
    int findchar(char)const;

    // Precondition: Insert a valid String
    // Postcondition: Return and integer with the position that
    // start that String, if don't return 0
    int findstring(String)const;

    String& operator=(const String&);

    // Precondition: 2 valid strings (LHS + RHS)
    // Postcondition: Return a String with that 2 values
    // concatenated
    String operator+(String)const;

    // Precondition: 2 valid strings (LHS and RHS)
    // Postcondition: return a boolean that say if this
    // 2 strings are equal
    bool operator==(String)const;

    // Precondition: 2 valid strings (LHS and RHS)
    // Postcondition: return a negation of the operator==
    bool operator!=(String)const;

    // Precondition: Receive 2 values (LHS and RHS)
    // Postcondition: Return a boolean that say if the
    // LHS is less than RHS using the lexicographical order
    bool operator<(String)const;

    // Precondition: Receive 2 values (LHS and RHS)
    // Postcondition: Return a negation of the operator<
    bool operator>(String)const;

    // Precondition: Receive 2 values (LHS and RHS)
    // Postcondition: Return a boolean that say if the
    // LHS is less or equal to RHS using the lexicographical
    // order
    bool operator<=(String)const;

    // Precondition: Receive 2 values (LHS and RHS)
    // Postcondition: Return a boolean that say if the
    // LHS is greater or equal to RHS using the lexicographical
    // order
    bool operator>=(String)const;

    // Precondition: LHS be a String and LRS be a String too
    // Postcondition: Return inside LHS the concatenation
    // of LHS and RHS
    String& operator+=(const String&);

    // Overload of the C++ output method
    friend std::ostream& operator<<(std::ostream&, const String&);
private:

    char *value;
    int  capacity;

};


#endif // CS2_STRING_H

String.cpp:

// String.cpp

#include "String.hpp"
#include <cstring>

//CONSTRUCTORS
String::String(){

    capacity = SIZE;

    value = new char[capacity];
    value[0] = '\0';

}

String::String(const char *ch){

    capacity = SIZE;

    int i =0;
    while(ch[i] != '\0'){
        i++;
    }

    value = new char[capacity];

    i=0;

    while(ch[i] != '\0'){
        value[i] = ch[i];
        i++;
    }

    value[i] = '\0';

}

String::String(const char ch){

    capacity = SIZE;

    value = new char[2];
    value[0] = ch;
    value[1] = '\0';
}

String::String(int tsize, const char *ch){
    int i =0;
    while(ch[i] != '\0'){
        i++;
    }
    if(tsize>=i){
        value = new char[capacity];
        i=0;
        while(ch[i] != '\0'){
            value[i] = ch[i];
            i++;
        }
        value[i] ='\0';
    }else{
        std::cout << "Error in the initialization, please the size need to be bigger." << std::endl;
    }
}

String::String(int tsize){
    if(tsize>=0){
        capacity = tsize;
        value = new char[capacity];
        value[0] = '\0';
    }
}

String::String(const String& rhs){
    int i = 0;
    capacity = rhs.capacity;
    value = new char[capacity];
    while(rhs[i] != '\0'){
        value[i] = rhs[i];
        i++;
    }
    value[i]='\0';
}

String::~String(){
    delete[] value;
}

void String::resize(int tsize){
    char *temp = value;
    capacity = tsize;
    value = new char[capacity];
    int i = 0;
    while(temp[i] != '\0'){
        value[i] = temp[i];
        i++;
    }
    value[i] = '\0';
    delete temp;
}

int String::getCapacity()const{
    return capacity;
}

int String::length()const{
    int i = 0;
    while(value[i]!='\0'){
        i++;
    }
    return i;
}

char String::getChar(int position)const{
    if(position>=0){
        return value[position];
    }
}

char String::operator[](int position)const{
    if(position>=0){
        return value[position];
    }
}

void  String::swap(String& rhs){
    int tempc = capacity;
    capacity = rhs.getCapacity();
    rhs.capacity = tempc;

    char *tempStr = value;
    value = rhs.value;
    rhs.value = tempStr;
}

String String::substring(int initial, int end)const{
    char newChar[256];
    int aux = 0;
    if(( ((initial >= 0) && (initial <= end)) ) && ( ((end > 0) && (end < SIZE)) ) ){
        for(int i = initial;i <= end;i++){
            newChar[aux]=value[i];
            aux++;
        }
    }
    String treturn(newChar);
    return treturn;
}

int String::findchar(char rhs)const{
    int x = 0;
    for(int i = 0;i < SIZE;i++){
        if( value[i] == rhs ){
            x = (i + 1);
            break;
        }
    }
    return x;
}

int String::findstring(String rhs)const{
    int x = 0, aux = 0;
    int lhssize = length();
    int rhssize = rhs.length();
    while(value[x]!='\0'){
        if(value[x]==rhs[aux]){
            aux++;
            if(aux==rhssize){
                return ( (x + 1) - rhssize);
            }
        }else{
            aux = 0;
        }
        x++;
    }
    return 0 ;
}

String& String::operator=(const String& str){
    int i = 0;
    while(str[i]!='\0'){
        value[i] = str[i];
        i++;
    }
    return *this;
}

String String::operator+(String rhs)const{

    char newChar[SIZE];
    int aux = 0;

    int max = this->length() + rhs.length();

    for(int i = 0; i < this->length(); i++){
        newChar[aux] = this -> getChar(i);
        aux++;
    }

    for(int i = 0; i < rhs.length(); i++){
        newChar[aux]=rhs.getChar(i);
        aux++;
    }

    String newString(newChar);

    return newString;

}

// OK
bool String::operator==(String rhs)const{
    int i=0;
    while(value[i] != '\0'){
        if(value[i] != rhs.value[i]){
            return false;
            i++;
        }
    }
    return value[i]==rhs.value[i];
}

bool String::operator!=(String rhs)const{
    String test(value);
    return !(test==rhs);
}

bool String::operator<(String rhs)const{
    int i =0;
    while( (value[i]!='\0') && (value[i] == rhs.value[i]) ){    
        i++;
    }
    return value[i] < rhs.value[i];
}

bool String::operator>(String rhs)const{

    String test(value);

    return !(test<rhs);
}

bool String::operator<=(String rhs)const{

    int i =0;

    while( (value[i] != '\0') && ( value[i] == rhs[i] ) ){
        i++;
    }

    return value[i] <= rhs[i];
}

bool String::operator>=(String rhs)const{

    int i =0;

    while( (value[i] != '\0') && (value[i] == rhs[i]) ){
        i++;
    }

    return value[i] >= rhs[i];

}

String& String::operator+=(const String& rhs){

    int offset = length();
    int i = 0;

    while(rhs[i] != '\0'){
        value[i+offset] = rhs[i];
        i++;
    }
    value[i+offset] = '\0';

    return *this;
}

std::ostream& operator<<(std::ostream& out,const String& rhs){

    int i=0;

    while(rhs[i] != '\0'){
        out << rhs[i];
        i++;
    }

    return out;
}

和InfixToPostfix.cpp:

#include "../String.cpp"
#include "../Stack.hpp"

int main(){
    Stack<String> S;
    String result, right, left, oper;
    String elements("((A+B)*C)");
    int i;
    for(i=0;i<elements.length();i++){
        char t = elements[i];
        if(t == ')'){
            right = S.pop();
            oper = S.pop();
            left = S.pop();
            S.push(left + right + oper);
        }else if(t != '('){
            S.push(t);
        }
    }
    return 0;
    result = S.pop();
    std::cout << result << std::endl;
}

// AB+C*

我真的不知道这是一个很好的方式,请求帮助人员,但我不知道该怎么办。我使用Subfime Text和UTF-8进行编码,并使用我大学的unix服务器进行编译。谢谢你们。

1 个答案:

答案 0 :(得分:0)

在代码中查看我的评论。这是在你的代码中打印出垃圾的罪魁祸首:

String& String::operator=(const String& str){
  int i = 0;
  while(str[i]!='\0'){
    value[i] = str[i];
    i++;
  }
  value[i] = '\0'; // <- You must still set the string terminator
  // or else garbage characters will be read until a null terminator is reached
  return *this;                                                                                                                                                
}

我必须指出的一件事是你在如何销毁物体时遇到了一些问题。 e.g;

template<class T>
Stack<T>::~Stack(){
  node<T> *curr, *pnext;
  curr = TOS;
  while(curr != NULL){
    pnext = curr -> next;
    delete curr;
    curr = pnext;
  }
  // delete TOS; // You already deleted the root node! This will result in segfault/double free                                                                                                                                             
}

最后,您必须修复代码的这一部分:

template<class T>
T Stack<T>::pop(){
  using namespace std;
  node<T> *p;
  T item;
  if(TOS != NULL){
    item = TOS -> nodeValue;
    p = TOS;
    TOS = TOS -> next;
    //    return p -> nodeValue; // How can you delete the node if you are already returning in this line?                                                                                                                              
    delete p;
  } else {
    std::cout << "Empty stack!" << std::endl;
  }

  return item; // Your function needs to return a proper value in both cases above
}