Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualChad Smith

Posted 29 November 2012 - 01:57 AM

Hey everyone, this fall semester I had a couple of University Programming Projects for the Computer Science class I was in. I was wonder if I could get some advice on the code I wrote for them. The projects are completely finished and have been completely graded. I will start with just the second project we had (The first one was pretty easy and I did post the code to it here a couple months ago).

The second project we had was to create our own bare bones basic stack class and use that to convert basic infix to postix
Example:
[source lang="cpp"]5+5 -> 55+or5+5-3 -> 55+3-[/source]
we did not have to have it be able to use parenthesis.

The requirements were to create our own stack class (bare bones basic) and we could not use the std::stack class in STL. The user would just have to type in convert, a basic infix expression and then convert. We had to do some basic error checking (like the user didn't just type in "5/" though we were allowed to assume some things (though I did try to check for only integer input)

I am wondering if some people could take a look at the code and see how it is. What are some things you would improve? Advice? Comments? Suggestions? I will take any input!
Also the grade I made on this was a 99, with one point being taken off because most of the code was in main.cpp and didn't split it into multiple functions. Though a 99 was the lowest grade I made out of all my other programming assignments with me making 100's on the rest (will post later on after input with this one, to get input on those). The Teacher Assistant seemed to like my solutions a little more than others though it seemed, so I was glad to hear that.

NOTE: I wrote the static CommandProcessor class to use on all my projects to try to help me with the command input

EDIT: I did have more of my functions in the Stack class returning NULL if they failed or something like that, though when I had to upload it the command line compiler that the servers used (a linux compiler) did not like me using NULL in those places, so I just replaced those with a return ' ' instead. I don't seem to be the biggest fan of the compiler used on the servers, but oh well. Visual Studio has zero problems with my code with me using NULL.

CommandProcessor.h
[source lang="cpp"]//CommandProcessor Header File//Class for CommandProcessor//Static Class to for processing commands and arguments//only include once in the compiling/linking process#ifndef COMMANDPROCESSOR_H#define COMMANDPROCESSOR_H//string for working with C++ strings#include <string>class CommandProcessor{public: //ExtractCommand will extract the command that was entered static std::string ExtractCommand(std::string& line); //ExtractArgument will extract the argument that was entered in the command static std::string ExtractArgument(std::string& line); //CheckArgument will make sure their is an argument in the command static bool CheckArgument(std::string& line);};#endif[/source]
CommandProcessor.cpp
[source lang="cpp"]//CommandProcessor Class Definition Source File//Definition for Static Class CommandProcessor//include the header file for the class#include "CommandProcessor.h"//start the class definitionsstd::string CommandProcessor::ExtractCommand(std::string& line){ //hold the index/location of the space in the command int index=line.find(" "); //if the string does not contain a space it will return string::npos if(index==std::string::npos) { //return the entire line //no arguments found return line; } else { //return the command up until the arguments start return line.substr(0, index); }}std::string CommandProcessor::ExtractArgument(std::string& line){ //hold the index/location of the space in a line int index=line.find(" "); //if the string does not contain a space, return an empty string if(index==std::string::npos) { return ""; } else { //return a substring //from one character after the space to the end of the line //length-index-1 to take account for the characters we don't need and the one space we moved over return line.substr(index+1, line.length()-index-1); }}//CheckArgument will make sure that an argument is present in the command//returns true if the argument was present//returns falsee if the argument was not presentbool CommandProcessor::CheckArgument(std::string& line){ //if argument is not an empty string then we consider it a valid argument //will keep program specific argument checking outside this class for code reusability if(line=="") { return false; } //the argument was not a empty string, consder it valid right now and return true return true;}[/source]

Node.h
[source lang="cpp"]//Node.h//Header file for the Node Struct//Declares the Node Struct#ifndef NODE_H#define NODE_H//Node Struct//A node simply is a datatype, build as a structstruct Node{ //the data in the node will hold both operators and numbers. int data; //point to the next node in the stack Node* nextNode;};#endif[/source]
Stack.h
[source lang="cpp"]//Stack.h//Header file to declare the Stack Class#ifndef STACK_H#define STACK_H//include iostream so we can compare things to NULL#include <iostream>//Stack will use the Node datatype#include "Node.h"//start the clas declaration of the List based Stackclass Stack{private: //hold a pointer to the first Node in the stack Node* firstNode; //hold the size of the current stack int size;public: //Public methods for working generally with stacks //Public default constructor Stack(); //Push will put some data onto the Stack void Push(char data); //Pop will remove the first element or Node char Pop(); //prints out the data of the first node char Top();};#endif[/source]

Stack.cpp
[source lang="cpp"]//Stack class definition source file//Define what the Stack class is//include the Stack header file#include "Stack.h"Stack::Stack(){ //the first pointer is null or empty at the start firstNode=NULL; size=0;}//Push Method//Takes in a char datatype and pushes the data onto the top of the Stackvoid Stack::Push(char data){ //create a temporary Node at first Node* tempNode=new Node(); //store the data needed into the temporary node tempNode->data=data; //before we push make sure that the first node isn't null if(firstNode!=NULL) { //the first node isn't null //the next node in the list now holds the first node tempNode->nextNode=firstNode; //the first node in the list now holds the tempNode, or the newNode that needs to be entered firstNode=tempNode; } //if anything else then we now know the firstNode is null else { //since it was empty already we can simply add the new node the list //be setting the firstNode equal to the new tempNode firstNode=tempNode; tempNode->nextNode=NULL; } //increase the size size++;}char Stack::Pop(){ char dataReturn=firstNode->data; //check to make sure the size of the stack is not empty //since we increased the size evertime we added a new node, we can just check the size if(size<=0) { //we can't pop anything off the stack if it is empty return ' '; } //create a temporary node to hold the first node Node* tempNode=firstNode; //the first node is now the node that was next firstNode=firstNode->nextNode; delete tempNode; size--; return dataReturn;}//returns the char data in the top node on the stack//will return null if the stack is empty and the top of the stack is nullchar Stack::Top(){ if(firstNode==NULL) { return ' '; } return firstNode->data;}[/source]
and finally Main.cpp
[source lang="cpp"]//Program2//Infix to Postfix//Main.cpp//Main Source file for Program2//iostream for console input and output#include <iostream>//include the static class CommandProcessor#include "CommandProcessor.h"//Include Stack for a stack#include "Stack.h"//Function Prototypes//Check to see if the string passed in is valid argumentbool ValidArgument(std::string& input);//Do the conversion of infix to postfix in this functionvoid Convert(std::string& input);//Checks to see if the characters in the arguments are numbers or operatorsbool IsNumber(char input);//Checks to see if the given operator is equal or lower to another operatorbool IsLowerOperator(char readingOperator, char stackOperator);//main entry pointint main(){ //the beginning text that gets added on to just about everything const std::string BEGINNING_TEXT= "infix_to_postfix> "; //hold the input std::string input; //hold the command input string std::string commandInput=""; //hold the argument input string std::string argumentInput=""; //boolean variable to know when the program should keep running or not //running will be true when we need to keep running. false when we should quit bool running=true; while(running) { std::cout<<BEGINNING_TEXT; std::getline(std::cin, input); commandInput=CommandProcessor::ExtractCommand(input); argumentInput=CommandProcessor::ExtractArgument(input); //if we need to convert if(commandInput=="convert") { if(ValidArgument(argumentInput)) { Convert(argumentInput); } else { std::cout<<"Error! Not a valid argument!"<<std::endl; } } //command was to quit else if(commandInput=="quit") { running=false; } //command was not reconized else { std::cout<<"Error! Command not reconized!"<<std::endl; } } //return 0 for no error return 0;}bool ValidArgument(std::string& input){ //boolean variable to keep track weather or not the input was valid bool validInput=false; if(CommandProcessor::CheckArgument(input)) { //argument was not empty //loop through the string to make sure it is a valid postfix //only numbers and operators for(unsigned int i=0; i<input.length(); i++) { //if the postfix argument was not a number or a operator set validInput to false; if(!(input[i]=='0'||input[i]=='1'||input[i]=='2'||input[i]=='3'||input[i]=='4'||input[i]=='5'||input[i]=='6'||input[i]=='7'||input[i]=='8'||input[i]=='9' //check for numbers ||input[i]=='+'||input[i]=='-'||input[i]=='*'||input[i]=='/')) //check for all the operators { validInput=false; //break out of the loop break; } else { validInput=true; } } } //we now know that the argument was empty else { validInput=false; } return validInput;}//Takes in a input string and converts it from Infix to Postfixvoid Convert(std::string& input){ std::string output; //a stack will hold the operators Stack postFix; //loop through the input string for(unsigned int i=0; i<input.length(); i++) { //check to see if the character is a number or operator if(IsNumber(input[i])) { //it is a number, it goes straight to the output output+=input[i]; } else { //first check to see if there was anything on the stack //if not then push the operator onto the stack if(postFix.Top()==' ') { postFix.Push(input[i]); } //if the operator is of lower or equal precedence then pop the operator on top and append it to the output until the top element is no longer higher precedence else if(IsLowerOperator(input[i], postFix.Top())) { do { output+=postFix.Pop(); } while(IsLowerOperator(input[i], postFix.Top())); postFix.Push(input[i]); } //the operator is of higher precendence, just push it onto the stack else { postFix.Push(input[i]); } } } //we are outside the for loop, all the elements are read, pop all the elements //keep "popping" until the top element is NULL while(postFix.Top()!=' ') { output+=postFix.Pop(); } std::cout<<output<<std::endl;}//Returns true if the input character is a number//returns false if it is a operatorbool IsNumber(char input){ //if the input is an operator return false if(input=='*'||input=='/'||input=='-'||input=='+') { //number is an operator return false return false; } //return true because we now know it has to be a number //this function would not be called if an alpha character was in the string return true;}//Returns true if the first operator is lower or equal precedence to the one on top of the stack//returns false if it is notbool IsLowerOperator(char readingOperator, char stackOperator){ //is the value of equal or lower precedence if((readingOperator=='-'&&stackOperator=='+')||(readingOperator=='-'&&stackOperator=='-')||(readingOperator=='+'&&stackOperator=='-')||(readingOperator=='+'&&stackOperator=='+') ||(readingOperator=='-'&&stackOperator=='*')||(readingOperator=='-'&&stackOperator=='/')||(readingOperator=='+'&&stackOperator=='*')||(readingOperator=='+'&&stackOperator=='/') ||(readingOperator=='*'&&stackOperator=='*')||(readingOperator=='*'&&stackOperator=='/')||(readingOperator=='/'&&stackOperator=='/')||(readingOperator=='/'&&stackOperator=='*')) { //return true as the operator was of equal or lower precendence return true; } //it is not lower or equal value, return false else { return false; }}[/source]

#1Chad Smith

Posted 29 November 2012 - 01:47 AM

Hey everyone, this fall semester I had a couple of University Programming Projects for the Computer Science class I was in. I was wonder if I could get some advice on the code I wrote for them. The projects are completely finished and have been completely graded. I will start with just the second project we had (The first one was pretty easy and I did post the code to it here a couple months ago).

The second project we had was to create our own bare bones basic stack class and use that to convert basic infix to postix
Example:
[source lang="cpp"]5+5 -> 55+or5+5-3 -> 55+3-[/source]
we did not have to have it be able to use parenthesis.

The requirements were to create our own stack class (bare bones basic) and we could not use the std::stack class in STL. The user would just have to type in convert, a basic infix expression and then convert. We had to do some basic error checking (like the user didn't just type in "5/" though we were allowed to assume some things (though I did try to check for only integer input)

I am wondering if some people could take a look at the code and see how it is. What are some things you would improve? Advice? Comments? Suggestions? I will take any input!
Also the grade I made on this was a 99, with one point being taken off because most of the code was in main.cpp and didn't split it into multiple functions. Though a 99 was the lowest grade I made out of all my other programming assignments with me making 100's on the rest (will post later on after input with this one, to get input on those). The Teacher Assistant seemed to like my solutions a little more than others though it seemed, so I was glad to hear that.

NOTE: I wrote the static CommandProcessor class to use on all my projects to try to help me with the command input

CommandProcessor.h
[source lang="cpp"]//CommandProcessor Header File//Class for CommandProcessor//Static Class to for processing commands and arguments//only include once in the compiling/linking process#ifndef COMMANDPROCESSOR_H#define COMMANDPROCESSOR_H//string for working with C++ strings#include <string>class CommandProcessor{public: //ExtractCommand will extract the command that was entered static std::string ExtractCommand(std::string& line); //ExtractArgument will extract the argument that was entered in the command static std::string ExtractArgument(std::string& line); //CheckArgument will make sure their is an argument in the command static bool CheckArgument(std::string& line);};#endif[/source]
CommandProcessor.cpp
[source lang="cpp"]//CommandProcessor Class Definition Source File//Definition for Static Class CommandProcessor//include the header file for the class#include "CommandProcessor.h"//start the class definitionsstd::string CommandProcessor::ExtractCommand(std::string& line){ //hold the index/location of the space in the command int index=line.find(" "); //if the string does not contain a space it will return string::npos if(index==std::string::npos) { //return the entire line //no arguments found return line; } else { //return the command up until the arguments start return line.substr(0, index); }}std::string CommandProcessor::ExtractArgument(std::string& line){ //hold the index/location of the space in a line int index=line.find(" "); //if the string does not contain a space, return an empty string if(index==std::string::npos) { return ""; } else { //return a substring //from one character after the space to the end of the line //length-index-1 to take account for the characters we don't need and the one space we moved over return line.substr(index+1, line.length()-index-1); }}//CheckArgument will make sure that an argument is present in the command//returns true if the argument was present//returns falsee if the argument was not presentbool CommandProcessor::CheckArgument(std::string& line){ //if argument is not an empty string then we consider it a valid argument //will keep program specific argument checking outside this class for code reusability if(line=="") { return false; } //the argument was not a empty string, consder it valid right now and return true return true;}[/source]

Node.h
[source lang="cpp"]//Node.h//Header file for the Node Struct//Declares the Node Struct#ifndef NODE_H#define NODE_H//Node Struct//A node simply is a datatype, build as a structstruct Node{ //the data in the node will hold both operators and numbers. int data; //point to the next node in the stack Node* nextNode;};#endif[/source]
Stack.h
[source lang="cpp"]//Stack.h//Header file to declare the Stack Class#ifndef STACK_H#define STACK_H//include iostream so we can compare things to NULL#include <iostream>//Stack will use the Node datatype#include "Node.h"//start the clas declaration of the List based Stackclass Stack{private: //hold a pointer to the first Node in the stack Node* firstNode; //hold the size of the current stack int size;public: //Public methods for working generally with stacks //Public default constructor Stack(); //Push will put some data onto the Stack void Push(char data); //Pop will remove the first element or Node char Pop(); //prints out the data of the first node char Top();};#endif[/source]

Stack.cpp
[source lang="cpp"]//Stack class definition source file//Define what the Stack class is//include the Stack header file#include "Stack.h"Stack::Stack(){ //the first pointer is null or empty at the start firstNode=NULL; size=0;}//Push Method//Takes in a char datatype and pushes the data onto the top of the Stackvoid Stack::Push(char data){ //create a temporary Node at first Node* tempNode=new Node(); //store the data needed into the temporary node tempNode->data=data; //before we push make sure that the first node isn't null if(firstNode!=NULL) { //the first node isn't null //the next node in the list now holds the first node tempNode->nextNode=firstNode; //the first node in the list now holds the tempNode, or the newNode that needs to be entered firstNode=tempNode; } //if anything else then we now know the firstNode is null else { //since it was empty already we can simply add the new node the list //be setting the firstNode equal to the new tempNode firstNode=tempNode; tempNode->nextNode=NULL; } //increase the size size++;}char Stack::Pop(){ char dataReturn=firstNode->data; //check to make sure the size of the stack is not empty //since we increased the size evertime we added a new node, we can just check the size if(size<=0) { //we can't pop anything off the stack if it is empty return ' '; } //create a temporary node to hold the first node Node* tempNode=firstNode; //the first node is now the node that was next firstNode=firstNode->nextNode; delete tempNode; size--; return dataReturn;}//returns the char data in the top node on the stack//will return null if the stack is empty and the top of the stack is nullchar Stack::Top(){ if(firstNode==NULL) { return ' '; } return firstNode->data;}[/source]
and finally Main.cpp
[source lang="cpp"]//Program2//Infix to Postfix//Main.cpp//Main Source file for Program2//iostream for console input and output#include <iostream>//include the static class CommandProcessor#include "CommandProcessor.h"//Include Stack for a stack#include "Stack.h"//Function Prototypes//Check to see if the string passed in is valid argumentbool ValidArgument(std::string& input);//Do the conversion of infix to postfix in this functionvoid Convert(std::string& input);//Checks to see if the characters in the arguments are numbers or operatorsbool IsNumber(char input);//Checks to see if the given operator is equal or lower to another operatorbool IsLowerOperator(char readingOperator, char stackOperator);//main entry pointint main(){ //the beginning text that gets added on to just about everything const std::string BEGINNING_TEXT= "infix_to_postfix> "; //hold the input std::string input; //hold the command input string std::string commandInput=""; //hold the argument input string std::string argumentInput=""; //boolean variable to know when the program should keep running or not //running will be true when we need to keep running. false when we should quit bool running=true; while(running) { std::cout<<BEGINNING_TEXT; std::getline(std::cin, input); commandInput=CommandProcessor::ExtractCommand(input); argumentInput=CommandProcessor::ExtractArgument(input); //if we need to convert if(commandInput=="convert") { if(ValidArgument(argumentInput)) { Convert(argumentInput); } else { std::cout<<"Error! Not a valid argument!"<<std::endl; } } //command was to quit else if(commandInput=="quit") { running=false; } //command was not reconized else { std::cout<<"Error! Command not reconized!"<<std::endl; } } //return 0 for no error return 0;}bool ValidArgument(std::string& input){ //boolean variable to keep track weather or not the input was valid bool validInput=false; if(CommandProcessor::CheckArgument(input)) { //argument was not empty //loop through the string to make sure it is a valid postfix //only numbers and operators for(unsigned int i=0; i<input.length(); i++) { //if the postfix argument was not a number or a operator set validInput to false; if(!(input[i]=='0'||input[i]=='1'||input[i]=='2'||input[i]=='3'||input[i]=='4'||input[i]=='5'||input[i]=='6'||input[i]=='7'||input[i]=='8'||input[i]=='9' //check for numbers ||input[i]=='+'||input[i]=='-'||input[i]=='*'||input[i]=='/')) //check for all the operators { validInput=false; //break out of the loop break; } else { validInput=true; } } } //we now know that the argument was empty else { validInput=false; } return validInput;}//Takes in a input string and converts it from Infix to Postfixvoid Convert(std::string& input){ std::string output; //a stack will hold the operators Stack postFix; //loop through the input string for(unsigned int i=0; i<input.length(); i++) { //check to see if the character is a number or operator if(IsNumber(input[i])) { //it is a number, it goes straight to the output output+=input[i]; } else { //first check to see if there was anything on the stack //if not then push the operator onto the stack if(postFix.Top()==' ') { postFix.Push(input[i]); } //if the operator is of lower or equal precedence then pop the operator on top and append it to the output until the top element is no longer higher precedence else if(IsLowerOperator(input[i], postFix.Top())) { do { output+=postFix.Pop(); } while(IsLowerOperator(input[i], postFix.Top())); postFix.Push(input[i]); } //the operator is of higher precendence, just push it onto the stack else { postFix.Push(input[i]); } } } //we are outside the for loop, all the elements are read, pop all the elements //keep "popping" until the top element is NULL while(postFix.Top()!=' ') { output+=postFix.Pop(); } std::cout<<output<<std::endl;}//Returns true if the input character is a number//returns false if it is a operatorbool IsNumber(char input){ //if the input is an operator return false if(input=='*'||input=='/'||input=='-'||input=='+') { //number is an operator return false return false; } //return true because we now know it has to be a number //this function would not be called if an alpha character was in the string return true;}//Returns true if the first operator is lower or equal precedence to the one on top of the stack//returns false if it is notbool IsLowerOperator(char readingOperator, char stackOperator){ //is the value of equal or lower precedence if((readingOperator=='-'&&stackOperator=='+')||(readingOperator=='-'&&stackOperator=='-')||(readingOperator=='+'&&stackOperator=='-')||(readingOperator=='+'&&stackOperator=='+') ||(readingOperator=='-'&&stackOperator=='*')||(readingOperator=='-'&&stackOperator=='/')||(readingOperator=='+'&&stackOperator=='*')||(readingOperator=='+'&&stackOperator=='/') ||(readingOperator=='*'&&stackOperator=='*')||(readingOperator=='*'&&stackOperator=='/')||(readingOperator=='/'&&stackOperator=='/')||(readingOperator=='/'&&stackOperator=='*')) { //return true as the operator was of equal or lower precendence return true; } //it is not lower or equal value, return false else { return false; }}[/source]

PARTNERS