2013-12-05 4 views
-1

Я работаю над программой, использующей шаблоны для оценки постфиксных выражений. Мне не разрешено каким-либо образом модифицировать код; заполняйте пробелы, так сказать (большинство из них заполнено, но появляются ошибки). Это говорит о том, что:Template novice

1) Заголовок шаблона, специализация шаблона и основные файлы программы являются отдельными. Как реализовать шаблон в основной программе? Я уже использую #include в конце файла заголовка в качестве замены специализации.

2) FIXED

3) В файле специализация, нужно ли мне использовать #include «templateheader.h» выше, с использованием патезраса, или я просто поставить шаблон выше каждую функцию? Я отправлю пример, как сейчас.

Две звездочки обозначают линии, где мы должны заполнить пробелы. Если это только часть линии, это одна звезда с каждой стороны.

stackType.h

#pragma once** 
// Catherine Stringfellow and Trey Brumley 
// A Stack is a ???** 

// Class specification for Stack ADT in file StackType.h 
using namespace std; 

static const int MAXITEMS = 50; 

template <class stack>** 
class StackType 
{ 
    public: 
    // Class constructors 
    StackType(); 
    StackType (const StackType & other); 

    void makeEmpty(); 
    // Function: Sets stack to an empty state. 
    // Post: Stack is empty. 

    bool isFull() const; 
    // Function: Determines whether the stack is full. 
    // Pre: Stack has been initialized. 
    // Post: Function value = (stack is full) 

    bool isEmpty() const; 
    // Function: Determines whether the stack is empty. 
    // Pre: Stack has been initialized. 
    // Post: Function value = (stack is empty) 

    void push(*stack* item); 
    // Function: Adds newItem to the top of the stack. 
    // Pre: Stack has been initialized. 
    // Post: If (stack is full), PushOnFullStack exception is thrown; 
    //  otherwise, newItem is at the top of the stack. 

    void pop(*stack* & item); 
    // Function: Removes top item from the stack and returns it in item. 
    // Pre: Stack has been initialized. 
    // Post: If (stack is empty), PopOnEmptyStack exception is thrown; 
    //  otherwise, top element has been removed from stack. 
    //  item is a cop of the removed item. 

    int getStackNum(); 
    //Function: returns the number of items in the stack 
    //Pre: Stack has been initialized 
    //Post: Returns the number of items in the stack 

private: 
    int top; 
    stack items[MAXITEMS]; //statically allocated array 
}; 

#include "stackType.cpp";** 

stackType.cpp

// Catherine Stringfellow and Trey Brumley 
// File: StackType.cpp 

// Templated member function implementations for class StackType. 
// This is the statically allocated array-based stack. 

#include "stack"** 
using namespace std; 

template <class stack>** 
StackType *StackType<stack>*::StackType() 
{ 
    top = -1; 
} 

template <class stack>** 
StackType *StackType<stack>*::StackType (const StackType & other) 
{ 
    top = other.top; 
    for (int i=0; i < top; i++) 
     items[i] = other.items[i]; 
} 

template <class stack>** 
StackType*<stack>*::makeEmpty() 
{ 
    top = -1; 
} 

template <class stack>** 
*bool StackType<stack>*::isEmpty() const 
{ 
    return (top == -1); 
} 

template <class stack>** 
bool StackType*<stack>*::isFull() const 
{ 
    return (top == MAXITEMS-1); 
} 

template <class stack>** 
StackType*<stack>*::push(StackType newItem) 
{ 
    if(!isFull()) 
    { 
    top++; 
    items[top] = newItem; 
    } 
} 

template <class stack>** 
StackType*<stack>*::pop(& item) 
{ 
    if(!isEmpty()) 
    { 
    item = items[top]; 
    top--; 
    } 
} 

template <class stack>** 
int StackType*<stack>*::getStackNum() 
{ 
    return top+1; 
} 

главный

/* Erik Malone and Catherine Stringfellow and Trey Brumley     Date: December-5-2013 
    File: prog5.cpp 

    Program Specifications 
     Narrative: Program that evaluates and converts postfix expressions. 
     Interface: 
      Introductory Screen: 
       "Postfix Calculator and Converter" 
      Exit Screen: 
       "Goodbye..." 
      Input: 
       numbers in expressions should be separated by a space. 
       (from keyboard, see attached) 

      Output: 
       (all to screen, see attached) 
     Constants: 
      STACK_MAX 
*/ 

#include "stack"** 
#include <string> 
#include <iostream> 
#include <cmath> 
#include <iomanip> 
#include <cstdlib> 
#include <cctype> 

int getValidChoice(); 
/* purpose: get valid option choice from menu 
    prereq: NONE 
    postcond: int (for a valid choice returned) 
*/ 

void readString(string& s); 
/* purpose: Reads a line into a string 
    recieves: string <s> 
    returns: NONE 
*/ 
void printString(const string& s); 
/* purpose: Prints a string 
    recieves: const string <s> 
    returns: NONE 
*/ 
void convertPostfix(string& post, string& result); 
/* purpose: converts a prefix expression to infix 
    recieves: string <post>, string <result> 
    returns: NONE 
*/ 
void convert(StackType & s, char ch); 
/* purpose: pops two operands off a string stack and pushes the result 
    recieves: string <post>, char <ch> 
    returns: NONE 
*/ 
void evalPostfix(string& post, double& answer); 
/* purpose: calculates the value of the prefix expression 
    recieves: string <post>, double <answer> 
    returns: NONE 
*/ 
void evaluate(StackType & s, char ch); 
/* purpose: pops two operands off a double stack and pushes the result 
    recieves: Stack <s>, char <ch> 
    returns: NONE 
*/ 

void error(int m); 
//prints an error message, based on int parametet 

//print the introduction and exit screens 
void intro(); 
void outro(); 

void main() 
{     
    string post; 
    double answer; 
    int choice; 

    //intro screen 
    intro(); 

    //while user wants to continue 
    choice = getValidChoice(); 
    while (choice != 3) { 

     //switch menu options 
     switch (choice)       
     { 
     case 1: 
      cout<<"Please enter a postfix expression: "; 
      readString(post); 
      if (post == "")        //error if string empty 
       error(1); 
      else 
      { 
       evalPostfix(post, answer); 
       printString(post); 
       cout<<" = "<<answer<< endl << endl; 
      } 
      break; 

     case 2: 
      cout<<"Please enter a postfix expression: "; 
      readString(post); 
      if (post == "") 
       error(1); 
      else 
      { string tempString = ""; 
       convertPostfix(post, tempString); 
       cout<<"Postfix expression: "; 
       printString(post); 
       cout<<"\nEpression converted to infix: "<<tempString << endl<<endl; 
      } 
      break; 
      default: //if choice is not recognized print error 
       error(3); 
     } //end switch 

     choice = getValidChoice(); 
    } //end while 

    outro();  

    //exit screen on return 
    system("pause"); 
} 

int getValidChoice() 
{              
    int choice; 

    //display menu options 
    cout<<" Options        \n"; 
    cout<< " (1) Evaluate postfix expression " << endl; 
    cout<< " (2) Convert postfix to infix " << endl; 
    cout<< " (3) Quit  " << endl; 

    //get menu option 
    cout<<"Enter option: "; 
    cin>>choice; 
    cout <<endl; 

    //validate menu option 
    while ((choice < 1) || (choice > 3)) { 
     cout << "Enter a value between 1 and 3: "; 
     cin >> choice; 
    } 

    return choice; 
} 

void printString(const string& s) 
{ 
    if (s.empty()) 
     cout<<"Empty";         //if string is empty print "empty" 
    else 
     cout<<s; 
} 

void readString(string& s) 
{ 
    char temp[40]; 
    cin.ignore(80,'\n');        //clear buffer 
    cin.getline(temp, 40);        //copy line to string 
    s = temp; 
} 

void evalPostfix(string& post, double& answer) 
{ 
    int index = 0, total = 0;     
    double tempDbl; 
    bool negative = false;    //to detect negative signs 
    StackType s;      //declare a stack of doubles 

    //loop index until end of string 
    while (index < (int) post.length())      
    { 
     //pass over spaces in string 
     while (isspace(post[index]))      
      index++ ; 

     //if operator evaluate incrementing index 
     if (!isdigit(post[index]) && 
      !((index+1 < (int) post.length()) && 
       (post[index] == '-' && isdigit(post[index+1])))) 
     //if (!isdigit(post[index])) 
      evaluate(s, post[index++]);     
     else 
     { //if number, checks for negative sign 
      if (post[index] == '-')      
      { 
       index++; 
       negative = true; 
      } 

      //add up the digits from string 
      while ((post[index] >= '0') && (post[index] <= '9')) 
       total = (total * 10) + (post[index++] - '0'); 

      //if there was a negative sign, negate total 
      if (negative)        
      { 
       total = total * -1; 
       negative = false; 
      } 

      //push number onto stack 
      s.push(total);        
      total = 0; 
     } 

     index++; 
    } 

    //pop answer from stack 
    s.pop(tempDbl);          
    answer = tempDbl; 

} 

void evaluate(StackType & s, char ch) 
{ 
    double op1, op2;          

    //check if empty before popping operands 
    if (!s.isEmpty())         
    { 
     s.pop(op2); 

     if (!s.isEmpty()) 
     { 
      s.pop(op1); 

      //push result 
      switch(ch)         
      { 
      case '+': 
       s.push(op1 + op2);      
       break; 
      case '-': 
       s.push(op1 - op2); 
       break; 
      case '*': 
       s.push(op1 * op2); 
       break; 
      case '/': 
       s.push(op1/op2); 
       break; 
      default: 
       return; 
      } 
     } 
    } 
} 

void convertPostfix(string& post, string& result) 
{ 
    int index = 0; 
    string tempString; 
    StackType s; //declare a stack of strings 

    //loop index until end of string 
    while (index < (int) post.length())      
    { 
     //pass over spaces in string 
     if (isspace(post[index]))      
      index++ ; 

     //if operator convert incrementing index 
     if (!isdigit(post[index]) && 
      !((index+1 < (int) post.length()) && 
       (post[index] == '-' && isdigit(post[index+1])))) 
     //if (!isdigit(post[index])) 
      convert(s, post[index++]);     
     else 
     { 
      //clear string 
      tempString.erase();       

      //concatenate numbers to string 
      while (!isspace(post[index]))    
       tempString = tempString + post[index++]; 

      //push string onto stack 
      s.push(tempString);       
     } 

     index++; 
    } 
    //pop resulting string from stack 
    s.pop(result);          
} 

void convert(StackType & s, char ch) 
{ 
    string op1, op2, tempString; 

    //check if empty before popping 
    if (!s.isEmpty())         
    { 
     s.pop(op2); 

     if (!s.isEmpty()) 
     { 
      s.pop(op1); 

      //constructing string for result 
      tempString = tempString + "(";    
      tempString = tempString + op1;    

      //concatenate sign to string 
      switch(ch)         
      { 
      case '+': 
       tempString = tempString + " + ";   
       break; 
      case '-': 
       tempString = tempString + " - "; 
       break; 
      case '*': 
       tempString = tempString + " * "; 
       break; 
      case '/': 
       tempString = tempString + "/"; 
       break; 
      default: 
       return; 
      } 

      //adding rest of the string 
      tempString = tempString + op2;    
      tempString = tempString + ")"; 

      //push resulting string onto stack 
      s.push(tempString);       
     } 
    } 
} 

void error(int m) 
{ 
    system("cls");   //clear screen 
    cout<<"\a";    //system beep 

    //displays error message according to parameter passed 
    switch (m)           
    { 
    case -1: 
     cout<<"INTERNAL ERROR"; 
     break; 
    case 1: 
     cout<<"ERROR - Postfix expression empty."; 
     break; 
    case 3: 
     cout<<"ERROR - invalid entry."; 
     break; 
    default: 
     cout <<"UNKNOWN ERROR."; 
    } 
    cout << endl << endl; 
} 

void intro() 
{ 
    system("cls");          //clear screen 
    //displays welcome message 
    cout<<"Postfix Calculator and Converter\n\n"; 
} 

void outro() 
{ 
    cout<<"Goodbye...\n\n";        //display exit message 
} 
+1

Совершенно неясно, что вы можете изменить. И добавив "#include" stackType.cpp ";" в конце файла заголовка неверно. Возможно, вы могли бы написать свой собственный код - что-то короткое и простое - что бы иллюстрировать концепцию, которую вы пытаетесь понять, тогда мы могли бы помочь вам в работе *, которая работает. – Beta

+0

1) Полагая, что включение в конце файла заголовка, похоже, работает, и именно так нам сказали сделать это, заявив, что это по существу то же самое, что и вся специализация после фактического заголовка, сохраняя их в отдельные файлы. 2) Я поставлю две звезды (**) рядом со всеми местами, где мы должны заполнить. –

+0

Это для класса INFO 3200 в Университете Оберн? – Potatoswatter

ответ

0

Что касается 2) он должен быть STD :: строка, или вы могли бы сказать

using std::string; 

или

using namespace std; 

, а затем вы должны быть в состоянии сказать только строку. Я бы рекомендовал бывший, если вы не втягивая много материала из станд ::

Другие биты пустяков:

  • имя файл заголовка «stack.h»
  • вы не нужен stack.cpp, просто реализуйте функции в stack.h, например

    описание товара template класс Stack { .... void doSomething (ElementType & объект) {...} .... };

Это, как правило, чище. Вы также можете сделать это из линии, но он все еще должен быть в том же файле, и если вы делаете это вне линии, вы должны префикс все функции с шаблоном ключевого слова

  • вы можете выберите более подробное описательное имя, чем «стек» для аргумента шаблона.
+0

Добавление фиксированной точки пространства имен std 2. Я думаю, что я удалил ее, когда приступил к запуску ошибок, но я удалил ее из неправильного файла и забыл вернуть ее обратно. Благодарю. –

0

Вы должны переключить имя своего класса с именем аргумента шаблона, что имеет смысл.Это станет

template <typename StackType> 
class Stack 
{ 
... 
}; 

Например

void push(stack item); 

Было бы

void push(StackType item); 

1) Вы можете поместить объявление и определение методов в отдельные файлы, но вам необходимо включить их в конце, как и вы, но я предлагаю вам переименовать файл stack.cpp в stack.inl (.inl for inline) или что-то еще.

3) Если вы используете 2 файла, как указано выше, нет необходимости включать stack.h внутри stack.cpp/inl. Подумайте об этом, как о том же файле. И будьте осторожны с этим использованием пространства имен std, поскольку все, кто включает ваш stack.h, будут «использовать пространство имен std», и это может вызвать проблемы ...

Наконец, в вашем исходном коде нет специализации по шаблону, и нет такого вещь как файл специализации. Тем не менее, специализация шаблонов действительно существует, и это, вероятно, не то, что вы ожидаете. Больше информации here

Смежные вопросы